複数のディレクトリがあり、各ディレクトリには次の行を含むファイルが含まれています。
../a_a_q1.out ../a_a_q2.out ../a_a_q3.out
a_a
すべてのサブディレクトリを繰り返し、そのセクションを現在のサブディレクトリ名に変更したいと思います。たとえば、サブディレクトリがと呼ばれる場合は、awesome_directory
次の行を読む必要があります。
../awesome_directory_q1.out ../awesome_directory_q2.out ../awesome_directory_q3.out
どうやってこれを達成できますか?
サブディレクトリ名のみを使用したいです。たとえば、awesome_directory
トランザクション全体(//something/server/user/other_stuff/more/awesome_directory
)の代わりに()部分のみが必要です。
答え1
Bashの2つの段階には、次の1つの方法があります。
epwd=$(basename `pwd`)
sed -i "s/a_a/$epwd/g" <filename>
この変数には、$epwd
sedで使用できるエスケープされたディレクトリ名が含まれています。 sed コマンドは、a_a のすべての発生を作業ディレクトリーに置き換えます。
編集:元の回答の最初の行は、フルパスではなく現在のディレクトリ名のみを含むように編集されました。フルパスを使用するには
epwd=$(pwd|sed 's/\//\\\//g')
答え2
これまで私はこれを思い出しました。
var=("${PWD##*/}")
sed -i "s/a_a/$var/g" filename
答え3
set '%s_q1.out %s_q2.out %s_q3.out\n'
:|for d in several directories
do cd -P -- "$d" || ! break
set "$1" "../${PWD##*/}"
{ sed -ne'\|\( \.\./a_a_q[123]\.out\)\{3\}|q;s/.//p'
printf "$@" "$2" "$2"; cut -c2-
} <<-IN >./infile
$(paste -d\ - ./infile)
IN
done
sed
これはPOSIXおよび、、、、、bash
シェルなどで機能します。または、シェルを使用すると、ここにある文書が通常のファイルでサポートされる可能性が低いため、共有入力をサポートするために必要な機能に頼ることはできません。このような場合は、上記のシェルのいずれかに切り替える必要があります。zsh
ksh
mksh
dash
yash
lseek()
GNUを使用する場合sed
だけ。sed -une
sed -ne
分析は次のとおりです。
まず、パラメータがあります。フォーマット文字列を繰り返し使用し、次のように設定します
set
。printf
$PWD
$OLDPWD
.
次に、プロジェクトの繰り返しを開始します。
several directories
。これが実際のディレクトリでもシンボリックリンクでも、-P
物理的な標準パス名を$PWD
取得set
します$2
。次に起こるのは、heredocリダイレクトの一番下で起こります。シェルが私たちのために保護する安全な一時ファイルにすべてを
paste
読み込み、各行の./infile
前にスペースを追加します。その後、シェルは一時ファイルをstdinに設定して./infile
再割り当てしますが、今回はstdoutとして割り当てます。sed
編集する場合はまれです。一致する行に会う前に、各行の最初の文字を削除してp
結果を印刷します。ラインに出会うとq
完全に入力されます - 何も印刷されません。ただし、stdoutに改行が続いて
printf
印刷され、中断された部分からstdinを選択します。../${PWD##*/}_q[123].out
cut
sed
(プレイラインの直後)各入力ラインから最初のバイトを削除しながら残りを読み込みます。
したがって、編集されたコンテンツ全体./infile
が前の位置に戻ります。
ああ、テストしてみました。
私は変わったseveral directories
パス名をいくつか変更しました/tmp
...
{ seq 7
echo '../a_a_q1.out ../a_a_q2.out ../a_a_q3.out'
seq 9 14
printf %s\\n '' '' ''
} >/tmp/infile
...一つ書いた/tmp/infile
次のようになります。
1 2 サム 4 5 6 7 ../a_a_q1.out ../a_a_q2.out ../a_a_q3.out 9 10 11 12 13 14
しかし、上記のコードスニペットを実行した後/tmp
...
cat /tmp/infile
1 2 サム 4 5 6 7 ../tmp_q1.out ../tmp_q2.out ../tmp_q3.out 9 10 11 12 13 14
答え4
そのa_a
部分が一定で、Linuxを実行している場合は、このrename
ユーティリティを使用できます。 Debian およびその派生製品では、コマンドは操作を実行しますが、構文が異なる他のユーティリティなので、 にrename
変更します。rename.ul
rename
ループを使用してディレクトリをナビゲートします。
for d in */; do … done
rename
各ディレクトリのファイル名を変更するために呼び出されます。
for d in */; do
rename /a_a "/${d%/}" "$d"a_a*
done