산출

산출

mapfile.txt내 Linux 컴퓨터에 다음과 같은 작은 텍스트 파일( )이 있습니다. 다른 디렉터리 및 하위 디렉터리에 있는 다른 파일의 이름을 바꾸려면 이 파일의 정보를 사용해야 합니다. 어떻게 해야 하나요?

질문 팁:

1.i need to rename the contents of the file .

2. we should match the any of  .config files in the folders and sub folders.The rename should as follows.Column 3 names in the input file should be renamed to column 2 names in the outfile.

3.Yes only the first field should be replaced.

나는 이것을 시도했습니다 :

s/search/replace/g 

하지만 이는 올바른 형식이 아닙니다.

지도 파일.txt:

PROJECT:DCMS_DEMO:prj1
BLOCK:de_top:blk1
BLOCK:new_block2:blk2
BLOCK:test:blk3
CHECKLIST:Block_DV:checklist1

기타 서류는 다음과 같습니다.

blk3 : 0% : 0%
blk1 : 0.68% : 0.99%
blk2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%

예상되는:

test : 0% : 0%
de_top : 0.68% : 0.99%
new_block2: 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%

답변1

그리고 awk:

awk -F ":" -v OFS=":" 'FNR==NR{a[$3" "]=$2" ";next} $1 in a{ $1=a[$1] };1' mapfile.txt otherfile.txt

산출:

test : 0% : 0%
de_top : 0.68% : 0.99%
new_block2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%

답변2

다음 솔루션을 적용하여 파일(또는 추가 파일)의 내용을 바꿀 수 있습니다.

먼저 다음과 같이 매핑 파일을 반복할 수 있습니다.

while IFS=: read -r desc new old;do   #IFS is used to set the delimiter, : in your case
echo "description=$desc - old value:$old - to be replaced with : $new" 
#i usually apply this echo as a cross check that all field are read correctly
#more actions here like:
#sed -i "s/$old/$new/g" file1
done <mapfile

위의 sed 줄의 주석 처리를 제거하면 Mapfile에서 읽은 변수를 사용하여 루프 내에서 sed를 호출하게 됩니다. 예를 들어
sed "s/prj1/DCMS_DEMO/g"Mapfile의 첫 번째 줄,
sed "s/blk1/de_top/g"Mapfile의 두 번째 줄 등입니다.

이 솔루션에는 함정이 있습니다. sed가 여러 번 호출되어 맵 파일의 각 줄을 한 번씩 읽으므로 성능이 저하됩니다.

작업 속도를 높이려면 마지막에 sed를 한 번 제공하는 "대체 스크립트"를 "구축"할 수 있습니다. 이를 위해 루프 내에서 다음과 같은 작업을 수행할 수 있습니다.

echo "s/$old/$new/g;" >>replacements

루프가 완료되고 전체 sed 교체 스크립트가 준비되면 다음과 같이 마지막에 sed를 한 번 호출할 수 있습니다.

sed -f replacements file1

sed 교체 스크립트를 사용한 데모

#!/bin/bash
clear
echo "Original File1"
cat file1
while IFS=: read -r desc new old;do
echo "s/$old/$new/g;" >>replacements
done <mapfile
echo && echo "Replacements for sed"
cat replacements
echo && echo "file1 replaced"
sed -f replacements file1
rm replacements

#Output:
Original File1   
blk3 : 0% : 0%   
blk1 : 0.68% : 0.99%
blk2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33% 

Replacements for sed
s/prj1/DCMS_DEMO/g; 
s/blk1/de_top/g; 
s/blk2/new_block2/g;   
s/blk3/test/g;
s/checklist1/Block_DV/g;

file1 replaced   
test : 0% : 0%   
de_top : 0.68% : 0.99%
new_block2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%

팁:
file1 사용법을 영구적으로 변경해야 하는 경우 sed -i
동일한 sed 스크립트를 디렉터리의 더 많은 파일에 적용해야 하는 경우 다음을 수행할 수 있습니다.
sed -i -f replacements * #or /dir/* or *.txt etc

답변3

find . -type f -name '*.config' -exec \
perl -wMstrict -Mvars='*h' -F':' -i -pale '
   BEGIN {
     local(@ARGV, $/) = shift;
     chop(local $_ = <>); print;
     %h = reverse /^[^:]+:\K(.+?):(.*)$/gm;
   }
   s//$h{$&}/ if exists $h{ (/\S+/g)[0] };
' mapfile.txt {} +

산출

test : 0% : 0%
de_top : 0.68% : 0.99%
new_block2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%

간단히

find현재 디렉토리에서 시작하는 모든 파일을 찾고 확장자를 가진 파일을 살펴보고 모드에서 열린 파일 .config한 입을 제공합니다 . 먼저 맵에서 해시를 생성한 다음 Perl 인수 목록의 모든 후속 파일에 적용합니다.Perlin-place edit -imapfile.txt

find . -type f -name '*.config' -exec \
perl -F: -i -ple '$. == ++$h and $h{$F[2]} = $F[1], 1 or exists $h{(/\S+/g)[0]} and s//$h{$&}/;
$h = 0 if eof' mapfile.txt {} +

관련 정보