一部のスクリプト名とそのパスはテキストファイルに保存されています。テキストファイルには、次のようなパスが含まれています。
/myhome/new1/myfiles/test2.sh
/myhome/new3/myfiles/test1.sh
/myhome/new2/myfiles/test4.sh
/myhome/new/myfiles/test5.sh
このシェルファイルは、いくつかの基本スクリプトによって呼び出されます。
ルートを選択したいです。パスにはデフォルトのパスがあります(パスの取得方法がわからず、最後の区切り文字を送信できません)。
sed 's/.*\///' new.txt
ファイル名をgrepして(使用されたファイル名を取得するために)保存したいと思います。シェル型ファイル名スクリプトはテキストファイルに書き込みます。
出力テキストファイルパス、スクリプト名、デフォルトのスクリプト名と同じでなければなりません。
/myhome/new1/myfiles/test2.sh test2 test2main.sh
/myhome/new3/myfiles/test1.sh test1 test1foo.sh
/myhome/new2/myfiles/test4.sh test4 test4bar.sh
/myhome/new/myfiles/test5.sh test5 baz5main.sh
test2main.sh
、、...はこれらのファイルを呼び出す主なスクリプトですtest1foo.sh
。testo4bar.sh
答え1
これを達成するには、次のスクリプトを使用できます。あなたの質問によると、各入力ファイルの「マスター」ファイルを正確に決定する方法は明確ではありません。以下のスクリプトでは、そのファイルがフォルダ内の他の唯一のファイルであると想定しています。
#!/usr/bin/env bash
while IFS= read -r f # every line is represented by $f
do
d=$(dirname "$f") # $f's directory
b=$(basename "$f") # $f's basename
bwoe=${b%.*} # $f's basename without extension
m=$(find "$d" -mindepth 1 -maxdepth 1 -not -name "$b" | head -n 1) # get first file in the folder that is not $f
m=$(basename "$m") # basename of main file
printf "%s\\t%s\\t%s\\n" "$f" "$bwoe" "$m"
done < input.txt # input.txt contains the input scripts
例:
$ ls a b c
a:
afoo.sh a.sh
b:
bmain.sh b.sh
c:
c.sh cxx.sh
$ cat input.txt
a/a.sh
b/b.sh
c/c.sh
$ bash script.sh
a/a.sh a afoo.sh
b/b.sh b bmain.sh
c/c.sh c cxx.sh
答え2
私が正しく理解した場合(コメントを参照)、コマンドを1行にするのに役立つ可能性があるコマンドのGNUsed
フラグがあります(テストされていない、申し訳ありません)。e
s
sed -E 'h;s_(.*/)(.*)_grep -l \2 \1*.sh_e;x;G;s_([^/]*).sh\n_\1.sh \1 _' scriptfile
h
後で台無しにした後に復元できるように、その行を予約済みスペースに保存してください。s_.*/_grep -l \2 \1*.sh_e
実際の秘密は、.*/
最後のスラッシュの前のすべての項目を一致させてパスになり、行の残りの\1
部分\2
(スクリプト名)になるようにすることです。これでgrep -l
スクリプト名の前とパスの前に挿入され/my/path/foo.sh
ますgrep -l foo.sh /my/path/*.sh
。このフラグはシェルでこのモードを実行するため、含まれているe
ファイルのリストに置き換えられます。 (1つだけあればいいです。そうでない場合はスクリプトを調整する必要があります。)*.sh
/my/path
foo.sh
- 残りは簡単です。
x
両方のバッファを変更し、予約済みバッファ(現在のシェルからの応答を含む)をパターンに追加します。 s_([^/]*).sh\n_\1.sh \1 _
クリーンアップを実行し、スクリプト名をコピーしないで改行を削除する.sh
と、必要な出力が得られます。
答え3
c-shell
真の救い主になることができる場所は次のとおりです。
% foreach line ( "`cat ./input.txt`" )
printf '%s\t%s\t' ${line:q} ${line:r:t:q}
printf '%smain\n' ${line:r:t:q}
end
他の方法は次のとおりです。
$ perl -F/ -pale '
my($t) = $F[-1] =~ /([^.]+)/;
$_ = join "\t", $_, $t, "${t}main" if /\S/;
' ./input.txt
$ sed -Ee '
s|([^/.]+)\.[^/.]+$|&\t\1\t\1main|;t
s|([^.]+)\.[^.]+$|&\t\1\t\1main|;t
s|([^/]+)$|&\t\1\t\1main|
' ./input.txt
結果:
/myhome/new1/myfiles/test2.sh test2 test2main
/myhome/new3/myfiles/test1.sh test1 test1main
/myhome/new2/myfiles/test4.sh test4 test4main
/myhome/new/myfiles/test5.sh test5 test5main
メモ:
o We have to be verbose as we need to cover the various possible cases that may arise.
o GNU sed is needed.
答え4
sed(-rオプション)では、キャプチャグループと拡張正規表現を使用してファイル名を取得し、最終出力で元の文字列をスクリプトに置き換えることができます。
sed -r 's/(^.*\/)([^.]*)(.*$)/\1\2\3 \2 \2main/' test.txt
(^.*\/) -- 1st Capture, the path
([^.]*) -- 2nd Capture, the file up to the dot
(.*$) -- 3rd Capture, the file suffix