파일이 있습니다abc.sh
search_dir='dummy'
filename='numbers.txt'
for entry in "$search_dir"/*
do
while read p;
do
sed -i '' "/$p/d" $entry
done < $filename
done
패턴이 일치하는 행을 삭제해 보세요. 기본적으로 패턴은 파일에서 전달하는 문자열일 뿐입니다. 그러나 불행히도 작동하지 않습니다.
내가 디버깅할 수 있었던 것은 올바른 모드에서 변수를 전달하지 않았다는 것입니다.
편집하다: 숫자.txt
2018061300006178
2018061300006179
2018061300006325
2018061300006326
2018061400006505
search_dir에 있는 파일의 내용은 다음과 같습니다.
1888~2018061400006505~0101~1~OWNED~SELF EMPLOYED~~~~3~~AGRICULTURE~~~OTHERS~AGRICULTURIST~~~AGRICULTURE~~~~~~~~N~N~Y~N~N~~300000-500000~~~49582E95361D5FA0C10C4C419B2940591C17E94EF329C31047A6B7DE26E68638
1889~2018061400006505~0101~2~OWNED~SELF EMPLOYED~~~~32~~AGRICULTURE~~~OTHERS~AGRIC
그래서 Numbers.txt에는 2018061400006505가 포함되어 있고 파일에는 숫자 관련 데이터도 포함되어 있으므로 주어진 숫자와 일치하는 줄을 삭제하고 싶습니다.
답변1
sed
예제의 숫자에 사용 중인 구분 기호(기본값 /
) 가 포함되어 있지 않은 한 $p
코드의 는 정규식(모든 의미 포함)으로 해석됩니다.
귀하의 코드:
search_dir='dummy'
filename='numbers.txt'
for entry in "$search_dir"/*
do
while read p;
do
sed -i '' "/$p/d" $entry
done < $filename
done
$search_dir
여기서는 숫자가 포함된 파일의 모든 줄을 삭제하려고 합니다 $filename
. 이것이 효과가 있는지 여부는 치료 sed
방법 에 따라 다릅니다 -i ''
. 일부 구현의 경우 인수 없이 사용해야 sed
합니다 .-i
관련성 sed -i
및 이식성:sed -i(제자리에서 편집)를 사용하여 이식성을 달성하는 방법은 무엇입니까?
결과를 임시 파일에 쓴 다음 해당 파일을 원래 파일 이름으로 이동하는 것이 더 안전합니다.
for entry in "$search_dir"/*
do
while read p;
do
sed "/$p/d" "$entry" >"$entry.tmp" && mv "$entry.tmp" "$entry"
done <"$filename"
done
이렇게 하면 sed
어떤 구현을 사용하더라도 올바르게 작동할 수 있습니다. 일반적으로 말해서, 스크립트를 테스트할 때 파일을 내부적으로 변경하려고 시도하는 것은 좋지 않으므로 mv
스크립트가 다른 방식으로 작동하는 방식에 익숙해질 때까지 이를 주석 처리하는 것이 좋습니다.
일반적인 솔루션으로서 이것은 본질적으로 "데이터를 코드로 사용"하기 때문에 여전히 약간 안전하지 않습니다(숫자는 데이터이고 이를 sed
스크립트의 일부로 사용하고 있음). 즉, 숫자 파일의 숫자에 을 삽입하기 sed
만 하면 스크립트에서 구문 오류가 쉽게 발생할 수 있습니다./
작업이 매우 간단하므로 대신 를 사용할 수 있습니다 grep
. 이렇게 하면 내부 while
루프도 제거됩니다.
for entry in "$search_dir"/*
do
grep -Fv -f "$filename" "$entry" >"$entry.tmp" && mv "$entry.tmp" "$entry"
done
그러면 grep
해당 패턴이 파일에서 읽혀지고 파일 $filename
에 적용됩니다 . 패턴이 포함된 줄은 모두 삭제 합니다 .$entry
-v
-F
grep
아니요숫자를 정규식으로 해석하지만 고정 문자열로는 해석하지 않습니다. -f "$filename"
우리는 grep
그것으로부터 $filename
.
아래 디렉터리가 있을 수 있는 경우 $search_dir
다음 디렉터리를 건너뛰고 싶습니다.
for entry in "$search_dir"/*
do
[ ! -f "$entry" ] && continue
grep -Fv -f "$filename" "$entry" >"$entry.tmp" && mv "$entry.tmp" "$entry"
done
또 다른 안전한 방법은 위의 내용 과 해결 방법 awk
으로 인해 숫자가 일치하는 것입니다.sed
grep
어딘가에행 측면에서 보면 잘못된 행을 삭제할 수도 있습니다. 데이터에서 두 번째로 구분된 필드를 awk
쉽게 일치시킬 수 있습니다 .~
for entry in "$search_dir"/*; do
[ ! -f "$entry" ] && continue
awk -F '~' 'NR==FNR { num[$0]; next } !($2 in num)' "$filename" "$entry" >"$entry.tmp" &&
mv "$entry.tmp" "$entry"
done
프로그램 awk
은 먼저 숫자를 키로 사용하여 연관 배열/해시를 채운 다음 두 번째 구분 열이 해당 해시의 키가 아닌 $entry
파일의 각 행을 인쇄합니다.~