2

自動バックアップを作成するための簡単なシェル スクリプトを作成しています。basename を使用してディレクトリのリストを作成しようとしています。このリストを解析して、リストから最初と最後のディレクトリを取得します。

問題は、ターミナルで basename を使用すると、すべてうまくいき、希望どおりのリストが表示されることです。例えば:

basename -a /var/*/ 

/var 内のすべてのディレクトリのリストを、名前の末尾に / を付けずに 1 行に 1 つずつ表示します。しかし、スクリプト内で使用して basename に変数を渡すと、変数が一重引用符で囲まれます。

while read line; do
dir_name=$(echo $line)
basename -a $dir_name/*/ > dir_list.tmp
done < file_with_list.txt

+x で実行する場合:

+ basename -a '/Volumes/OUTROS/backup/test/*/'

したがって、結果は私が必要とするものではありません。

さて、ベースネームの問題を回避するには無数の方法があるに違いないことはわかっていますが、それでは何も学べませんよね? ;)

一重引用符を取り除く方法は? ディレクトリ名にスペースが含まれている場合はどうなりますか?

4

3 に答える 3

1

ディレクトリ名にスペースを含めることができる場合は、の値を引用符で囲む必要がありますdir_name(スペースが必要かどうかに関係なく、変数の展開にはこれをお勧めします)。

while read line; do
  dir_name=$line
  basename -a "$dir_name"/*/ > dir_list.tmp
done < file_with_list.txt

(jordanmが指摘しているように、変数代入のRHSを引用する必要はありません。)

于 2012-07-29T01:23:19.800 に答える
1

dir_list.tmpにリストされている各ディレクトリの下にあるディレクトリのリストを入力することが目標であると仮定するとfile_with_list.txt、これで十分です。

#!/bin/bash

inputfile=file_with_list.txt
outputfile=dir_list.tmp
rm -f "$outputfile"        # the -f makes rm fail silently if file does not exist

while read line; do

  # basic syntax checking
  if [[ ! ${line} =~ ^/[a-z][a-z0-9/-]*$ ]]; then
    continue
  fi

  # collect targets using globbing
  for target in "$line"/*; do
    if [[ -d "$target" ]]; then
      printf "%s\n" "$target" >> $outputfile
    fi
  done

done < $inputfile

ファイルを処理するツールを開発するときdir_list.tmpは、そのファイル内の特殊文字 (スペースを含む) に注意してください。

最初の文字がハイフンであるターゲットがエラーを引き起こさないように、printf代わりに使用していることに注意してください。echo

于 2012-07-31T15:18:29.253 に答える
0

これはうまくいくかもしれません

while read; do
  find "$REPLY" >> dir_list.tmp
done < file_with_list.txt
于 2012-07-29T02:23:59.700 に答える