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

내가 올바르게 이해했다면(주석 참조) 명령 을 한 줄로 만드는 데 도움이 될 수 있는 명령에 대한 GNU sed플래그가 있습니다 (테스트되지 않음, 죄송합니다).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포함된 파일 목록으로 대체됩니다. (하나만 있으면 좋겠습니다. 그렇지 않으면 스크립트를 조정해야 합니다.)*.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 

관련 정보