file1.txt 파일은 다음과 같은 줄을 포함합니다 :
/api/purchase/<hash>/index.html
예를 들면 다음과 같습니다.
/api/purchase/12ab09f46/index.html
file2.csv 파일은 다음과 같은 줄을 포함합니다 :
<hash>,timestamp,ip_address
예를 들면 다음과 같습니다.
12ab09f46,20150812235200,22.231.113.64
a77b3ff22,20150812235959,194.66.82.11
file1.txt에 해시 값이있는 모든 줄을 제거하여 file2.csv를 필터링하고 싶습니다. 말하자면 :
cat file1.txt | extract <hash> | sed '/<hash>/d' file2.csv
또는 이와 같은 것.
간단해야하지만 제대로 작동하지 않는 것 같습니다.
누구 든지이 작업에 대한 작업 파이프 라인을 제공 할 수 있습니까?
답변
cut -d / -f 4 file1.txt | paste -sd '|' | xargs -I{} grep -v -E {} file2.csv
설명:
cut -d / -f 4 file1.txt
첫 번째 파일에서 해시를 선택합니다
paste -sd '|'
모든 해시를 정규 표현식 ex에 결합합니다. H1|H2|H3
xargs -I{} grep -v -E {} file2.csv
인수로 이전 패턴 그렙 호출합니다, xargs를 교체한다 {}
의 내용으로STDIN
당신이 없다면 당신은 paste
그것을 대체 할 수 있습니다tr "\\n" "|" | sed 's/|$//'
답변
가능한 awk
해결책 :
awk 'NR == FNR { x[$4] = 1; next; } { if (!($1 in x)) print $0; }' FS="/" file1.txt FS="," file2.txt
먼저 (필드 구분자) “/”를 file1.txt
사용하여 읽고 해시 인 FS
field의 키 값으로 배열 x를 만듭니다 $4
. 다음으로 두 번째 파일 file2.txt
설정 FS
을 읽고 ,
필드의 값이 $1
배열의 키로 존재하지 않는지 x
확인하고 인쇄하지 않는지 확인하십시오.
의견에서 제안한 것과 같은 관용적 표현은 다음과 같습니다.
awk 'NR == FNR { x[$4] = 1; next; } !($1 in x)' FS="/" file1.txt FS="," file2.txt
답변
내용은 GNU가 나오지
sed -z 's%.*/\([^/]*\)/index.html\n%\1\\|%g;s%^%/%;s%\\|$%/d%' file1.csv |
sed -f - file2.csv
여기서 첫 번째 sed 는 sed 명령 형식으로 해시 목록을 생성 하고 입력에서 위의 명령을 읽은 다음 sed -script /12ab09f46\|a77b3ff22\|..../d
로 전송합니다 . grep
과 동일 -f -
grep -oP '[^/]*(?=/index.html$)' file1.csv | grep -Fvf - file2.csv
또는 perl-expresions가없는 경우 :
grep -o '[^/]*/index.html$' file1.csv |
grep -o '^[^/]*' |
grep -Fvf - file2.csv
또는 cut으로 더 좋습니다 :
cut -d/ -f4 file1.csv | grep -Fvf - file2.csv
답변
#!/bin/bash
cut -d, -f1 file2 | while read key ; do
#check for appearance in file1 with successful grep:
#exit status is 0 if pattern is found, only search for at least 1
#appearance -> to speed it up
if [[ $(grep -m 1 "/$key/" file1) ]] ; then
sed "/^$key,/d" -i file2
#note that we are gradually overwriting file2 (-i option),
#so make a backup!
fi
done
참고 탐색 침 있음 /$key/
과 ^$key,
결과 중 하나와 두 슬래시 (파일 1)으로 줄이거 나 콤마 (파일 2)에 의해 제 라인의 입구와 다음한다. 키가 다음과 같은 경우 안전합니다.
a,values
a1,values
파일 2 등에서
/api/../a1/../
/api/../a/../
파일 1에서
답변
방금 다음과 같은 라이너 하나를 시험해 보았습니다.
for i in `cat file1.txt | awk -F"/" '{print $4}'`; do echo "\n $i" ; sed -ri "/^$i,/d" file2.csv ; done
테스트하려면 먼저 -ri 를 -re 로 바꾸 십시오. -re 는 dry run을 수행하며 모두 정상이면 -ri를 사용 하여 실행할 수 있습니다.
답변
Gabriele Lana의 답변 외에도 표준 입력에서 컨텐츠를 읽으려면 BSD paste 명령을 대시로 지정해야합니다.
하나 이상의 입력 파일에 대해 ‘-‘가 지정된 경우 표준 입력이 사용됩니다. 표준 입력은 ‘-‘의 각 인스턴스에 대해 원형으로 한 번에 한 줄씩 읽습니다.
따라서 최종은 아래와 같이 변경해야합니다.
cut -d / -f 4 file1.txt | paste -sd '|' - | xargs -I{} grep -v -E {} file2.csv