bashスクリプトにファイルセットへの共通パスを提供する

bashスクリプトにファイルセットへの共通パスを提供する

次のスクリプトの目的は、pasteコマンドを介して複数のテーブルをマージして特定のディレクトリに配置することです。

for i in {1..30}
 do
 paste ./directory"$i"/table1.txt table2.txt ... table20.txt > ./merged_tables/tables_directory"$i".txt
done 

次のエラーが発生します。

 paste: file table2: No such file or directory

各テーブルにパスを作成するとうまくいきますが、パスを複数回作成したくありません。各テーブルにパスを作成せずにこれを行う方法はありますか?事前にありがとう

答え1

for (( i = 1; i <= 30; ++i )); do
    ( cd "directory$i" &&
      paste tableNC023.txt tableNC088.txt tableNC102.txt ... ) >"./merged_tables/tables_directory$i.txt"
done

cdこれはサブシェルにディレクトリを入力するために使用されます。cd成功すると、paste結合されたデータを生成するために使用されます。サブシェルの出力は、以前と同様に結果ファイルにリダイレクトされます。

サブシェルで実行されるので、次の反復のために「戻る」に戻るcd必要はありません。cd ..cd -cd "$OLDPWD"


よりきれいなコードの代替案:

tables=( tableNC023.txt tableNC088.txt tableNC102.txt
         more tables here )

for (( i = 1; i <= 30; ++i )); do
    ( cd "directory$i" &&
      paste "${tables[@]}" ) >"./merged_tables/tables_directory$i.txt"
done

私は純粋に個人的な好みに応じて代わりにfor (( i ... ))使用します。for i in {...}

答え2

for i in {1..30}
 do
 pushd directory"$i" >/dev/null 2>&1 || continue
 paste table1.txt table2.txt ... table20.txt > ../merged_tables/tables_directory"$i".txt
 popd >/dev/null 2>&1
done

答え3

すでに中かっこ拡張を使用しているので、ここでも使用できます。

..拡張機能が一連の数字(リテラル)を生成するようにします。

for i in {1..30}; do
    paste ./directory"$i"/table{1..20}.txt > ./merged_tables/tables_directory"$i".txt
done 

または手動でリストします(塗りつぶし...)。

for i in {1..30}; do
    paste ./directory"$i"/table{1,2,...,20}.txt > ./merged_tables/tables_directory"$i".txt
done 

つまり、パターンに一致するディレクトリ内のすべてのファイルを望まないと仮定します。

for i in {1..30}; do
    paste ./directory"$i"/table*.txt > ./merged_tables/tables_directory"$i".txt
done 

関連情報