때로는 클립보드에 파일이나 문자열 목록이 있고 이를 인수 목록으로 bash 셸에 붙여넣고 싶을 때가 있습니다.
예제 파일 목록(예제만):
createsnapshot.sh
directorylisting.sh
fetchfile.sh
내가 원하는 것은:
md5sum createsnapshot.sh directorylisting.sh fetchfile.sh
현재 다음과 같은 해킹 명령줄을 입력합니다(파일 이름은 클립보드에서 붙여넣어졌으며 목록에는 수십 줄이 포함될 수 있습니다).
md5sum $(echo $(echo "
createsnapshot.sh
directorylisting.sh
fetchfile.sh
"))
여기에는 몇 가지 단점이 있습니다.
- 복잡해
- 좋아 보이지 않는다
- 공백이 포함된 줄은 지원하지 않습니다.
다른 어떤 옵션이 있나요? md5sum "
이 경우 여러 줄 문자열이 있는 매개변수만 가져오기 때문에 작동하지 않습니다. 여기 문서와 유사합니다.
항상 그런 것은 아닙니다 md5sum
. tar
또는 git add
또는 일 수도 있습니다 du -hsc
. 나는 단지 이 파일들의 md5 체크섬을 얻는 방법을 요구하는 것이 아닙니다. 이런 일이 하루에 2~5회 정도 일어납니다.
답변1
백틱 호출과 같은 변수나 더미 변수를 인용하지 않는 경우 ( 예 $(xclip -selection c -o)
: 이 경우(클립보드의 내용을 먼저 확인하세요) 원하는 것은 다음과 같습니다.$IFS
\t
\n
md5sum `xclip -selection c -o`
노트:
필요한 명령 주위에 짧은 이름의 래퍼를 두는 것이 매우 편리합니다 xclip
.
나는 사용한다
#!/bin/sh
#filename: cb
if [ -n "$DISPLAY" ]; then
[ -t 0 ] && exec /usr/bin/xclip -selection c -o 2>/dev/null
/usr/bin/xclip -selection c
else
[ -t 0 ] && exec cat "/dev/shm/$TTY_DASHED"
cat > /dev/shm/"$TTY_DASHED"
fi
이를 통해 콘텐츠를 입력하여 cb
클립보드에 액세스하고 something | cb
콘텐츠를 작성할 수 있습니다.
DISPLAY
(내가 밖에 TTY_DASHED
있다면.profile
export TTY_DASHED=$(tty |tr / - | tail -c+2)
답변2
명령이 use 를 사용하지 않는 경우 입력을 읽고 이를 인수로 변환하는 stdin
it 을 사용하십시오 ( 명령을 작성하는 방법을 보여주기 위해 이 명령을 사용하고 있음에 유의하십시오).xargs
echo
xargs
$ xargs echo md5sum
# paste text
createsnapshot.sh
directorylisting.sh
fetchfile.sh
# press Ctrl-D to signify end of input
md5sum createsnapshot.sh directorylisting.sh fetchfile.sh
공백에도 불구하고 각 줄이 완전한 인수로 처리되도록 xargs
with를 사용합니다 .-d '\n'
$ xargs -d'\n' md5sum
# paste
a file with spaces
afilewithoutspaces
foo " " bar
# Ctrl D
md5sum: a file with spaces: No such file or directory
md5sum: afilewithoutspaces: No such file or directory
md5sum: foo " " bar: No such file or directory
보시다시피 md5sum
파일 이름의 다른 공백에 관계없이 모든 파일 이름에 대해 오류가 인쇄됩니다.
을 사용하려면 xclip
xargs에 파이프하거나 제공할 수 있습니다.
xargs -a <(xclip -o) -d '\n' md5sum
xclip -o | xargs -d '\n' md5sum
공백이 포함된 파일 이름을 안정적으로 처리해야 합니다.
답변3
파일 이름이 포함된 변수를 설정할 수 있습니다. 그런 다음 명령에서 해당 변수를 사용하십시오.
$ #VAR='<paste filenames>':
$ VAR='createsnapshot.sh
> directorylisting.sh
> fetchfile.sh'
$ touch $VAR
$ ls -l $VAR
-rw-r--r-- 1 testuser testuser 0 nov 26 12:47 createsnapshot.sh
-rw-r--r-- 1 testuser testuser 0 nov 26 12:47 directorylisting.sh
-rw-r--r-- 1 testuser testuser 0 nov 26 12:47 fetchfile.sh
$ md5sum $VAR
d41d8cd98f00b204e9800998ecf8427e createsnapshot.sh
d41d8cd98f00b204e9800998ecf8427e directorylisting.sh
d41d8cd98f00b204e9800998ecf8427e fetchfile.sh
$ tar cf archive.tar $VAR
$ tar tf archive.tar
createsnapshot.sh
directorylisting.sh
fetchfile.sh
참고: $VAR
줄 끝으로 인해 따옴표 없이 호출해야 합니다. VAR=$(echo "$VAR"|tr '\n' ' ') to be able to use quoted
$VAR` 사용을 고려할 수 있습니다.
위 내용을 기반으로 한 또 다른 접근 방식은 ~/.bashrc
include에 함수를 작성하는 것입니다.
fVAR ()
{
VAR="$@";
VAR=$(echo "$VAR"|tr '\n' ' ')
}
함수는 클립보드 내용으로 호출되며 fVAR
값은 다음에서 찾을 수 있습니다 $VAR
.
$ fVAR '<paste filenames>'
$ md5sum "$VAR"
답변4
set --
while IFS= read -r in
do set -- "$@" "$in"
done
...그럼 당신의교대 삽입키, 그럼Ctrl+D한 번(또는 두 번), 그러면 붙여넣기의 각 줄을 문자 그대로 소유할 수 있습니다.(NUL 없음)in $1
등 $2
이 있으며 $3
전체 입력 배열은 $IFS
in 의 첫 번째 문자에 연결된 단일 문자열 "$*"
또는 의 별도 문자열 목록 으로 처리될 수 있습니다 "$@"
. 즉, 다음을 수행할 수 있습니다.
md5sum -- "$@"
...유용한 대화형 속기를 찾고 계시기 때문입니다.
alias rdcb='
[ -t 0 ] && set -- &&
while IFS= read -r in
do set -- "$@" "$in"
done'
... alias
대화식 쉘에서 실행할 수 있는 명령을 정의하여 쉘의 인수를 표준 입력에서 개행으로 구분된 배열로 설정합니다.
그래서...
{ ls -1 | xsel -bi #pipes ls output into my clipboard
rdcb #terminal hangs, shift+insert && crtl+d
xsel -bo #writes my clipboard to stdout
printf %s\\n '' --- '' "$@" #writes \n-delimited shell arg array
printf %s\\n '' --- '' "$3" "$5" #writes only args "$3" and "$5"
}
1
edit.sh
paccache
sh
systemd-private-75115542eb544b09bc245e8ca7765854-systemd-timesyncd.service-CKruFk
sztally
yaourt-tmp-mikeserv
---
1
edit.sh
paccache
sh
systemd-private-75115542eb544b09bc245e8ca7765854-systemd-timesyncd.service-CKruFk
sztally
yaourt-tmp-mikeserv
---
paccache
systemd-private-75115542eb544b09bc245e8ca7765854-systemd-timesyncd.service-CKruFk
더 나은 버전은 다음과 같습니다.
alias rdcb='
if [ -t 0 ]
then set -f -- "$IFS" "${IFS+IFS=\$1;} set +f -$-
stty $(stty -g; stty raw -echo min 1 time 2)"
IFS=$(printf \\r)
set -- "$@" $(dd bs=4k count=1 2>/dev/null)
eval "unset IFS;$2;shift 2"
fi '
터미널 에코 및 터미널 특수 문자 처리를 포기하고 필요하지 않습니다.Ctrl+D입력이 끝났음을 나타냅니다. 수행하는 모든 작업은 일시적이며 영향을 미치는 모든 설정을 완료 시 발견한 상태로 신중하게 복원합니다. 물론 설계에 따라 영구적으로 변경되는 셸의 매개변수는 제외됩니다.
이렇게 하고 rdcb
붙여넣기만 하면 끝입니다. 붙여넣으면 화면에 출력이 없습니다. 터미널이 멈추고 10분의 1초 내에 최소 1바이트를 입력하면 프롬프트가 다시 나타납니다. 이후에는 이전과 같이 매개변수를 처리할 수 있습니다.