찾기 및 sed(찾기 및 삭제)

찾기 및 sed(찾기 및 삭제)

그 안에 여러 하위 폴더와 파일이 있는 폴더가 있습니다. 하위 폴더의 이름과 하위 폴더 내 파일의 패턴이 포함된 CSV 파일도 있습니다.

내가하고 싶은 것은 기본 폴더 내부의 while 루프를 사용하여 CSV 파일을 읽고 sed. 저는 bashUnix에서 다음 쉘 스크립트를 사용합니다:

IFS=","
while read f1 f2
do
 find $f2/ -name vcs*.pv -exec sed -i '/$f1/d' {} +
done > export.csv

실수:

find: 'ap01\r/': No such file or directory.

CSV 파일:

S2AEC67X1,ap01

값을 올바르게 읽고 있지만 f2나머지는 수행하지 않습니다. 모든 하위 폴더와 함께 기본 디렉터리에 CSV 파일을 저장합니다.

답변1

이것:ap01\r

있음을 나타냅니다.입력하다문자열 뒤에 api01. CSV 파일에서 삭제해 보세요.

업데이트: @RomanPerekhrest의 의견도 읽어보세요. 루프에서를 >a로 변경해야 합니다(실제로 그래야 하는 경우).<while사용사이클 while이지만 그것은 완전히 또 다른 토론입니다! ).

답변2

이 질문의 코드 및 입력 파일에는 몇 가지 문제가 있습니다.

  1. 입력 파일의 각 줄에는 \r분명히 후행 캐리지 리턴( )이 있습니다. 이는 Windows 컴퓨터에서 히트가 DOS 텍스트 파일로 생성되었기 때문일 수 있습니다. 이러한 캐리지 리턴을 제거하는 일반적인 방법은 dos2unix파일에서 실행하는 것입니다. 예를 들어 질문을 참조하세요."^M"은(는) 무엇이고 어떻게 제거하나요?

  2. 모든 변수 확장은 큰따옴표로 묶어야 합니다. 명령에서는 $f2따옴표 없이 디렉터리의 경로 이름을 사용합니다. 공백이 포함되어 있으면 실패합니다 $f2.

  3. 작은따옴표는 쉘이 변수를 확장하는 것을 방지합니다. 이는 sed스크립트가 리터럴 정규식과 일치하는 행을 찾는다는 것을 의미합니다 $f1. 이 정규식은 $줄의 끝만 일치하고 줄의 끝은 일치하지 않으므로 절대 일치하지 않습니다 .그런 다음 f1같은 줄에 문자를 포함시킵니다.. 큰따옴표로 스크립트를 편집하면 셸이 를 호출하기 전에 변수를 확장하게 sed됩니다 .$f1sed

  4. 패턴은 옵션에 대한 인수 vcs*.pv여야 하지만 따옴표가 없기 때문에 와일드카드 패턴과 일치하는 현재 디렉터리의 모든 이름으로 확장됩니다. 따라서 현재 디렉터리에 이라는 이름의 파일 이 있으면 해당 파일이 호출되어 해당 이름의 파일만 찾습니다. 현재 디렉터리에 일치하는 이름이 여러 개 있으면 알 수 없는 옵션에 대해 불평할 수 있습니다.-namefindvcs-test.pvfind-name vcs-test.pvfind

  5. 파일 export.csv은 출력됩니다(그리고 루프에서 출력이 발생하기 전에 비워집니다). 반복해서 읽으려고 할 수도 있습니다. 여기에는 >으로 변경하는 작업이 포함됩니다 <.

스크립트가 수정되었습니다:

while IFS=',' read f1 f2; do
    find "$f2" -type f -name 'vcs*.pv' -exec sed -i "/$f1/d" {} +
done <export.csv

실수로 디렉토리 이름을 가져오는 것을 원하지 않기 때문에 명령줄 -type f에도 추가했습니다 . 나는 또한 변수를 설정 find하기 위해 이것을했습니다IFS오직명령을 위해 read.


이는 모든 파일이 위치한 위의 변형입니다.곧장CSV 파일에서 이름을 읽은 최상위 디렉터리 아래:

while IFS=',' read dir pattern; do
    for name in "$dir"/vcs*.pv; do
        test -f "$name" && sed -i "s/$pattern/d" "$name"
    done
done <export.csv

이것 의 장점 은 당신 이 그것 을 피해갈 수 있다는 것입 니다 find. 단점은 이제 sed파일당 한 번씩 호출해야 한다는 것입니다(일반적으로 수백 개 이상의 파일이 없으면 문제가 되지 않습니다).

다음은 위의 변형으로 행을 제거합니다.CSV 파일에서 읽습니다. 차이점은 위의 코드 조각이 패턴을 다음과 같이 해석한다는 것입니다.정규식, 고정 문자열이 아닙니다. 문자열에 정규 표현식(예: , 등)에서 "특수"로 해석되는 문자가 포함된 경우 .이는 *중요 [합니다 .]

while IFS=',' read dir string; do
    for name in "$dir"/vcs*.pv; do
        [ ! -f "$name" ] && continue
        grep -v -F -e "$string" "$name" >"$name.tmp" && mv -f "$name.tmp" "$name"
    done
done <export.csv

관련 정보