sed 명령 i=를 사용하여 한 줄의 첫 번째 단어를 한 줄의 마지막 단어로 바꾸려고 하는데 알아낼 수 없는 것 같습니다.
답변1
사용 awk
:
awk '{ t=$1; $1=$NF; $NF=t; print}'
이는 다음을 수행합니다.
t=$1
-t
첫 번째 단어로 설정$1=$NF
- 첫 번째 단어를 마지막 단어로 설정$NF=t
- 마지막 단어를 첫 번째 단어로 설정print
- 새 줄을 인쇄합니다.
$ echo 'one two three four five six' | awk '{ f=$1; l=$NF; $1=l; $NF=f; print}'
six two three four five one
답변2
Perl을 사용하고 공백으로 구분된 입력과 공백으로 구분된 출력을 가정합니다.
perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@F\n"'
시험:
$ printf 'Cleanse Fold and Manipulate\n' | perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@F\n"'
Manipulate Fold and Cleanse
Perl 코드는 배열의 시작과 끝에서 두 요소를 간단히 교체한 다음 결과 목록을 공백으로 연결하고 끝에 개행을 추가하여 -a
공백의 입력을 배열로 분할 하는 데 사용됩니다.@F
첫 번째 단어와 마지막 단어를 일치시키고 대체 단어로 바꾸는 더 짧은 Perl 변형입니다(이는 입력에 측면 공백이 없다고 가정합니다):
perl -pe 's/^(\w*)(.*?)(\w*)$/$3$2$1/'
중간 비트는 .*?
문자열의 중간과 크게 일치하지 않습니다. sed
나중에는 이런 욕심없는 수식어가 없기 때문에 쉽게 할 수 없습니다 .?
.*
답변3
약간 진지한 답변: 당신이 아니어도 괜찮습니다. 문제는 전적으로 sed
명령 의 자세한 내용에 있습니다 s///
(대체 답변과 비교).
$ echo "Hello some good world!" |
sed 's/\(^[^[:space:]]\+\)\([[:space:]].*[[:space:]]\|[[:space:]]\+\)\([^[:space:]]\+$\)/\3\2\1/'
world! some good Hello
첫 번째 단어 앞이나 뒤에 공백 문자가 있는 경우에도 첫 번째 단어와 마지막 단어를 바꾸고 싶을 수도 있습니다(의견 및 기타 답변에 감사드립니다).
$ echo " Hello some good world! " |
sed 's/^\([[:space:]]*\)\([^[:space:]]\+\)\([[:space:]].*[[:space:]]\|[[:space:]]\+\)\([^[:space:]]\+\)\([[:space:]]*\)$/\1\4\3\2\5/'
world! some good Hello
그러나 이러한 명령은 BRE(기본 정규 표현식) 구문의 일부 비 POSIX GNU 확장(즉 +
및 |
)을 사용합니다.
교체()의 편리함을 유지하면서 POSIX 표준을 충족하는 (더 이식성이 높은) 명령에는 |
확장된 정규 표현식이 필요합니다. 예를 들어 옵션 sed
과 함께 GNU를 사용하면(이렇게 하면 GNU 확장이 비활성화됩니다. 실제로는 필요하지 않음):--posix
$ echo " Hello some good world! " |
sed --posix -E 's/^([[:space:]]*)([^[:space:]]{1,})([[:space:]].*[[:space:]]|[[:space:]]{1,})([^[:space:]]{1,})([[:space:]]*)$/\1\4\3\2\5/'
world! some good Hello
그러나 POSIX ERE 구문에는 역참조가 포함되지 않습니다. 또한 이 명령이 성공하려면 확장 기능을 구현해야 합니다.