sed: 다중 -e 또는 while 루프?

sed: 다중 -e 또는 while 루프?

값 튜플이 포함된 CSV 파일이 있는데 한 값의 발생 횟수를 다른(대형) 파일의 다른 값 발생 횟수로 변경해야 합니다.

지금까지 나는 한동안 읽기 라인 [...] < foo.csv를 수행해 왔으며 기본적으로 CSV 파일의 각 라인에 대해 sed를 한 번씩 실행했습니다.

이 작업은 꽤 오랜 시간이 걸리므로 while 루프를 변경하여 여러 개의 -e 문의 긴 문자열을 구성한 다음 eval을 사용하여 실행해야 하는지 궁금합니다.

분명히 시도해 볼 수 있지만 누군가가 sed가 내가 지금까지 했던 것과 동일한 일을 할 것인지, 즉 모든 -e 문에 대해 파일을 실행하는지 말해 줄 수 있다면 어떤 성능 향상도 없을 것이라고 추측할 수 있습니다. 나는 귀찮게하지 않을 것입니다.

댓글 후 수정:

기본적으로 다음을 수행합니다.

while read line
do
  old_user=echo $line | cut -d \; -f 2|tr -d \"
  new_user=echo $line | cut -d \; -f 4|tr -d \"

  if [ "$old_user" != "$new_user" ]
  then
    sed -i -e "s/^(.*ri:username=\")$old_user(\".*)$/\1$new_user\2/g" confluence/entities_converted.xml
  fi
done < usernames.csv

XML 파일인 것을 보면 그 이유는 많은 경우 XML을 구문 분석하고 다시 작성하는 것이 번거롭기 때문입니다. 그래서 ... 여러 번 실행하는 sed대신 여러 매개 변수를 구성해야 하는지 궁금합니다 .sed-esed

usernames.csv좋다

    "Full name";"Username";"Email";"New username"
    "Sune Mølgaard";"sune.molgaard";"[email protected]";"smo"

두 번째 선의 경로를 따라 여러 선이 있을 수 있으므로 원형입니다. 첫 번째 줄이 일치하지 않을 수도 있지만 그건 중요하지 않습니다.

답변1

여러 -e를 평가하거나 구성할 필요가 없습니다. Sed는 파일이나 파이프에서 "프로그램"을 읽을 수 있으며 실제로 sed에서도 해당 "프로그램"을 생성할 수 있습니다.

cut -f2,4 -d\; usernames.csv \
    | sed -e 's/^/s%ri:username=/' -e 's/;/%ri:username=/' -e 's/$/%/' \
    | sed -i~ -f- confluence/entities_converted.xml

생성된 프로그램을 확인하려면 마지막 줄을 삭제하세요.

변경할 필요가 없는 줄을 건너뛰려면(작업 속도를 높이기 위해) grepsed 사이에 다음을 삽입하여 제거하세요.

   | grep -v '"\(.*\)".*"\1"' \

답변2

awk를 사용하여 usernames.csv(필드 2와 4가 다름)를 구문 분석하고 sed 파일을 생성해야 합니다.

 tr -d \" username.csv |
 awk -F\; '$2 != $4 { printf "s/^(.*ri:username=%c)%s(%c.*)$/\\1%s\\2/g\n",34,$2,34,$4 ; }' |
 sed -i -f - confluence/entities_converted.xml

몇 가지 팁

  • 따옴표를 생성하려면 printf "..%c..",34를 사용하세요.
  • 모든 sed 명령어가 올바르게 생성되었는지 확인하려면 디버그 섹션에서 sed 줄을 건너뛸 수 있습니다.
  • /g교체가 필요합니까 ?

내 테스트 파일에

;foo;;foo;;
;fubar;;mr X;;
;bar;;bistro;;
    "Full name";"Username";"Email";"New username"
    "Sune Mølgaard";"sune.molgaard";"[email protected]";"smo"

이는

s/^(.*ri:username=")fubar(".*)$/\1mr X\2/g
s/^(.*ri:username=")bar(".*)$/\1bistro\2/g
s/^(.*ri:username=")Username(".*)$/\1New username\2/g
s/^(.*ri:username=")sune.molgaard(".*)$/\1smo\2/g

사용자 이름 줄을 제거하지 마세요. 찾을 수 없으면 바꿀 수 없습니다.

관련 정보