내 Linux 상자에는 매우 큰 호스트 파일이 있습니다.
1.1.1.1 hostA hosta
1.1.1.2 hostB hostb
1.1.1.3 hostC hostc
1.1.1.4 hostD hostd
1.1.1.5 hostE hoste
1.1.1.6 hostF hostf
1.1.1.7 hostG hostg
.......
수정하고 싶은 줄이 있습니다 file2
.
2.1.1.1 hostA hosta
2.1.1.2 hostB hostb
2.1.1.3 hostC hostc
따라서 원하는 출력은 다음과 같습니다.
2.1.1.1 hostA hosta
2.1.1.2 hostB hostb
2.1.1.3 hostC hostc
1.1.1.4 hostD hostd
1.1.1.5 hostE hoste
1.1.1.6 hostF hostf
1.1.1.7 hostG hostg
.......
나는 이것을 다음과 같이 사용하는 방법을 알고 있습니다.
sed '/hostA/ s/1.1.1.1/2.1.1.1/' hosts
for
하지만 루프에서 사용하는 방법을 모르겠습니다 . 아니면 호스트를 수정하는 또 다른 빠른 방법이 있습니까?
답변1
다음이 사용됩니다밀러( mlr
)는 파일을 헤더 없이 "예쁘게 인쇄된" 데이터로 읽은 다음 각 줄의 두 번째 및 세 번째 필드를 조인 키로 사용하여 hosts
파일 간의 왼쪽 조인 작업을 수행합니다.new
$ mlr --pprint -N join -j 2,3 -f hosts --ul then reorder -f 1,2,3 new
2.1.1.1 hostA hosta
2.1.1.2 hostB hostb
2.1.1.3 hostC hostc
1.1.1.4 hostD hostd
1.1.1.5 hostE hoste
1.1.1.6 hostF hostf
1.1.1.7 hostG hostg
reorder
마지막 작업은 입력에서 찾은 것과 동일한 순서로 필드를 다시 정렬합니다(그렇지 않으면 마지막 두 필드가 부분 데이터의 필드 1과 2로 사용됩니다).
답변2
2개의 GNU sed 호출을 사용하여 이를 수행할 수 있습니다. 예를 들면 다음과 같습니다.
sed -E 's:([^ ]+) +(.*):/\2/ s/^[^ ]+/\1/:' file2 |
sed -Ef - hosts
첫 번째는 sed
새로운 sed 스크립트를 생성합니다.
/hostA hosta/ s/^[^ ]+/2.1.1.1/
/hostB hostb/ s/^[^ ]+/2.1.1.2/
/hostC hostc/ s/^[^ ]+/2.1.1.3/
답변3
awk를 사용하십시오.
$ awk 'NR==FNR{ip[$2]=$1; next} $2 in ip{$1=ip[$2]} 1' file2 hosts
2.1.1.1 hostA hosta
2.1.1.2 hostB hostb
2.1.1.3 hostC hostc
1.1.1.4 hostD hostd
1.1.1.5 hostE hoste
1.1.1.6 hostF hostf
1.1.1.7 hostG hostg
또는 필드 사이의 공백을 유지하는 데 관심이 있는 경우:
awk 'NR==FNR{ip[$2]=$1; next} $2 in ip{sub(/[0-9.]+/,ip[$2])} 1' file2 hosts
$2
예제에서와 같이 실제로 각 행에서 두 개의 호스트 이름을 키로 사용해야 하는 경우 모든 $2
것을 로 변경하면 됩니다 ($2,$3)
.
답변4
변형:
$ cut -d' ' -f2 file2 > hostids
$ grep -v -f hostids hosts > newhosts
$ cat file2 >> newhosts
$ sort -t' ' -k2 newhosts > hosts