Используйте файл
на отправляющей машине и используйте эту информацию, чтобы решить, какую команду распаковки запускать на удаленном хосте.
например.
#! /bin/sh
filetype=$(file misteryCompressedFile)
case "$filetype" in
*gzip*) CMD='gzip' ; ARGS='-d -fc' ;;
*bzip2*) CMD='bzip2' ; ARGS='-d -fc' ;;
*) echo "error: unknown compression type" ; exit 1 ;;
esac
cat misteryCompressedFile | ssh user@ipaddr "$CMD $ARGS > /opt/files/uncompressedfile"
В показанном примере ARGS для команд gzip
и bzip2
одинаковы ... но они могут отличаться для других инструментов распаковки.
Вот версия, которая распаковывает файл, полученный с удаленного хоста:
#! /bin/sh
# set up an anonymous fifo on fd 3 so we can pass the
# output of `file` to the second subshell without risking
# corruption of stdout/stdin
FIFO=$(mktemp -u)
mkfifo "$FIFO"
exec 3<>"$FIFO"
rm -f "$FIFO"
ssh user@ipaddr 'cat misteryCompressedFile' |
(
HEADER=$(dd bs=1 count=20 2> /dev/null |
od -A none -t o1 -w512 |
sed -e 's: :\\:g')
printf "$HEADER" | file --mimetype - | cut -d/ -f2 >&3
printf "$HEADER"
cat
) | (
read -u 3 -r filetype
case "$filetype" in
gzip) CMD='gzip' ; ARGS='-d -fc' ;;
x-bzip2) CMD='bzip2' ; ARGS='-d -fc' ;;
x-xz) CMD='unxz' ; ARGS='' ;;
x-lzma) CMD='lzcat' ; ARGS='' ;;
x-compress) CMD='uncompress' ; ARGS='' ;;
x-lrzip) CMD='lrzcat' ; ARGS='' ;;
*) echo "error: unknown compression type" >&2 ; exit 1 ;;
esac
$CMD $ARGS > /opt/files/uncompressedfile
)
Conzsh
:
VAR1=tom:rich,LIAm:viki
VAR2=liam,albert,tom
typeset -A map
for i ("${(@s(,))VAR1}") map[${(L)i%%:*}]=${i#*:}
out=()
for i ("${(@s(,))VAR2}") out+=${(qq)${map[${(L)i}]:-$i}}
VAR3=${(j(,))out}
printf '%s\n' "$VAR3"
Salida:
'viki','albert','rich'
Lo mismo conawk
(que podría usar con zsh
, o cualquier Bourne -como shell comobash
):
VAR1=tom:rich,LIAm:viki
VAR2=liam,albert,tom
export VAR1 VAR2
awk -v q=\' 'BEGIN {
n = split(ENVIRON["VAR1"], a, ",")
for (i = 1; i <= n; i++) {
k = v = a[i]
sub(/:.*/, "", k)
sub(/[^:]*:/, "", v)
map[tolower(k)] = v
}
n = split(ENVIRON["VAR2"], a, ",")
for (i = 1; i <= n; i++) {
k = tolower(a[i])
out = out sep q (k in map ? map[k] : a[i]) q
sep = ","
}
print out
}'
(una diferencia es que aquí solo encerramos los valores entre comillas simples. Si el valor contiene comillas simples, como foo'bar
, obtienes 'foo'bar'
mientras que zsh
's ${(qq)var}
te daría'foo'\''bar'
).
La versión zsh
permite cualquier valor para los elementos. Pueden contener cualquier valor de byte, incluidos nueva línea y NUL o un valor vacío. El awk
no admitirá NUL, ya que no se pueden almacenar en variables de entorno y, según la implementación, puede ahogarse con elementos que contienen bytes que no forman caracteres válidos.
Tenga en cuenta que con ambos,VAR2=
se entiende como una lista vacía mientras que VAR2=,
se entiende como una lista de 2 elementos vacíos, no hay forma de expresar una lista de un elemento vacío.
Una soluciónbash
(4.0+ )que construye una tabla lookup
(una matriz asociativa )utilizando las teclas en mayúsculas -inferiores de VAR1
y los valores asociados. Luego revisa los valores en VAR2
y construye VAR3
con valores de la tabla de búsqueda, o de VAR2
si no hay ninguna clave en la tabla de búsqueda correspondiente a la cadena VAR2
actual.
VAR1=tom:rich,LIAm:viki
VAR2=liam,albert,tom
declare -A lookup
# build lookup table
while read -d, key_value; do
# $key_value is a string like "tom:rich", separate these into key and value:
IFS=: read key value <<<"$key_value"
# add lower-cased key to table with value
lookup[${key,,}]=$value
done <<<"$VAR1,"
# do lookups in table
while read -d, string; do
# get newstring from table, but use $string if there's no entry:
newstring=${lookup[${string,,}]:-$string}
# add $newstring to VAR3, with a delimiting comma unless VAR3 is empty
VAR3+="${VAR3:+,}'$newstring'"
done <<<"$VAR2,"
printf 'VAR3 = %s\n' "$VAR3"
Este código genera
VAR3 = 'viki','albert','rich'
Esto supone que los valores en VAR1
y VAR2
no contienen líneas nuevas.
Usando awk
basado enRS
(separador de registro):
VAR3=$(awk '
BEGIN{RS="[,\n]";FS=":";ORS=","}
NR==FNR{a[tolower($1)]=$2}
NR>FNR{printf "%s\047%s\047",(FNR>1?ORS:""),(a[$1]?a[$1]:$1)}
' <(echo "$VAR1") <(echo "$VAR2")
)
La matriz a
se llena con el contenido de VAR1
con el par clave y valor. Este se usa cuando se analiza la segunda variable y el valor se reemplaza si existe una entrada de matriz.