
Bashスクリプトがあります。
for j in "$(ls -d */)"; do
echo "$j"
echo "$j"
done
出力:
dir1/
dir2/
dir3/
dir1/
dir2/
dir3/
私が出力したいのは次のとおりです。
dir1/
dir1/
dir2/
dir2/
dir3/
dir3/
どうすればこのように出力できますか?
(これはおもちゃの例です。本物私が望むのは、ディレクトリにCDを挿入し、何かをし、再びCDを挿入することです。文字列接続を使用して同じことができることに気づきましたが、この動作が混乱しすぎて他の質問が見つかりませんでした。それで尋ねるかと思いました。 )
答え1
あなたのループは一つ繰り返します。この繰り返しでは、変数j
の値は次のとおりです。
dir1/
dir2/
dir3/
その後、2回出力します。
単一の文字列を繰り返すので、変数はこの値を取得しますls -d */
。
サブディレクトリを繰り返すには、次を使用します。
for dirpath in */; do
printf '%s\n' "$dirpath"
printf '%s\n' "$dirpath"
done
ls
ls
つまり、まったく使う必要はありません(視力検査のみ)。
cd
各反復ごとにディレクトリに入るには、サブシェルcd
で実行し、そこで実行する必要があるすべての操作を実行します。これにより、cd
現在の作業ディレクトリがサブシェルにローカルであるため、戻る必要はありません。
for dirpath in */; do
( cd -- "$dirpath" && some-command )
done
cd
現在の作業ディレクトリを変更する必要がある場合にのみ入力してくださいsome-command
。ほとんどの作業は元の作業ディレクトリで実行できます。
答え2
これは、実行中の出力を解析するls
良い方法ではありません。
しかし、そう言うと、あなたの質問は次のように引用されます。
rm -rf dir?
for j in 1 2 3; do mkdir dir$j; done
for j in $(ls -d */); do
echo "$j"
echo "$j"
done
dir1//
dir1//
dir2//
dir2//
dir3//
dir3//
投稿の引用符を使用すると、出力全体が引用ls
符で囲まれているため、次のように処理されます。議論、for
ループが一度だけ繰り返されるようにし、出力全体をls
引数として使用します。あなたのコードは出力全体を2回印刷しますls
。
例を書くより良い方法ls
は次のとおりです。
find . -type d -maxdepth 1 -mindepth 1 -exec printf '%s\n%s\n' "{}" "{}" \;