grepはテキストファイルからファイル名を読み取り、それを呼び出したシェルファイルの名前をテキストに印刷します。

grepはテキストファイルからファイル名を読み取り、それを呼び出したシェルファイルの名前をテキストに印刷します。

一部のスクリプト名とそのパスはテキストファイルに保存されています。テキストファイルには、次のようなパスが含まれています。

 /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.shtesto4bar.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フラグがあります(テストされていない、申し訳ありません)。es

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/pathfoo.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 

関連情報