Обычно я создаю следующий скрипт либо в /usr/local/bin
, либо в $HOME/bin
.
#!/bin/bash
HOSTNAME=`uname -n`
ARG=`echo $DISPLAY | sed -e "s/localhost/$HOSTNAME\/unix/"`
XAUTH=`/usr/bin/xauth -i -f ~/.Xauthority list ${ARG}`
echo "The following is used for graphical displays through ssh."
echo "Copy and paste the following commands AFTER you have \"su - [user]\""
echo "---------------- Copy below ------------------------------------"
echo "DISPLAY=$DISPLAY;export DISPLAY"
echo "/usr/bin/xauth -bi add \\"
echo "${XAUTH}"
echo "---------------- Copy above ------------------------------------"
Вы должны выполнить этот сценарий до, используя su
или sudo
. Став другим пользователем, вырежьте и вставьте вывод, как указано. Ваши программы X
должны работать.
[bschuck@dhcp-10-100-11-138 ~]$ bin/xtunnel
The following is used for graphical displays through ssh.
Copy and paste the following commands AFTER you have "su - [user]"
---------------- Copy below ------------------------------------
DISPLAY=localhost:10.0;export DISPLAY
/usr/bin/xauth -bi add \
dhcp-10-100-11-138/unix:10 MIT-MAGIC-COOKIE-1 \
b64ace6b49bb1b49c59679a2db6411eb
---------------- Copy above ------------------------------------
[bschuck@dhcp-10-100-11-138 ~]$ su - zippy
Password:
[zippy@dhcp-10-100-11-138 ~]$ DISPLAY=localhost:10.0;export DISPLAY
[zippy@dhcp-10-100-11-138 ~]$ /usr/bin/xauth -bi add \
> dhcp-10-100-11-138/unix:10 MIT-MAGIC-COOKIE-1
b64ace6b49bb1b49c59679a2db6411eb
[zippy@dhcp-10-100-11-138 ~]$ xclock &
[1] 6076
[zippy@dhcp-10-100-11-138 ~]$
Используйте
for i in `awk '/}/ {if (NR!=1) print "";next} \
{printf "%s ",$0,"}"}END{print ""}' yt.txt \
|awk '{print $1}'|sort|uniq \
`; \
do \
awk '/}/ {if (NR!=1) print "";next} \
{printf "%s ",$0,"}"}END{printf ""} \
' yt.txt \
|grep "$i"|sed 's/ /\n/g'|grep -v "$i"|sort|uniq \
|awk -v var="$i" ' NR==1 {printf var} {print $0} END {print "}"}' \
;done \
Та же команда в 1 строке ниже (для копирования)
for i in `awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"}END{print ""}' yt.txt|awk '{print $1}'|sort|uniq` ; do awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"}END{printf ""}' yt.txt|grep "$i"|sed 's/ /\n/g'|grep -v "$i"|sort|uniq|awk -v var="$i" ' NR==1 {printf var} {print $0} END {print "}"}' ;done
Объяснение:
Часть for
вернет вам уникальный заголовок блока (abcd/efgh/a.jar
,lkmn/opqr/b.zip
) и передать его в блок do
. Часть do
сначала будет grep
все строки для каждого заголовка, которые также будут включать дубликаты. Затем он исключит заголовок и объединит все оставшиеся строки под этим блоком заголовков, а затем добавит заголовок в первую строку. И хардкод }
в конце.
Пример
bash-4.2$ cat yt.txt
abcd/efgh/a.jar
{
abcd/efgh/a.class
cdef/ghij/b.class
klmn/opqr/c.class
}
lkmn/opqr/b.zip
{
abcd/efgh/a.class
cdef/ghij/b.class
}
abcd/efgh/a.jar
{
cdef/ghij/b.class
d.class
}
bash-4.2$ for i in `awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"} \
> END{print ""}' yt.txt |awk '{print $1}'|sort|uniq` \
> ; do awk '/}/ {if (NR!=1) print "";next} {printf "%s ",$0,"}"}END{printf ""}' yt.txt \
> |grep "$i"|sed 's/ /\n/g'|grep -v "$i"|sort|uniq \
> |awk -v var="$i" ' NR==1 {printf var} {print $0} END {print "}"}'\
> ;done
abcd/efgh/a.jar
{
abcd/efgh/a.class
cdef/ghij/b.class
d.class
klmn/opqr/c.class
}
lkmn/opqr/b.zip
{
abcd/efgh/a.class
cdef/ghij/b.class
}
После того, как я увидел решение, использующее цикл for
с awk
и sort
, и uniq
, и grep
, и sed
, я попробовал решение с одним инструментом вместо шести:
sed ':a
N;$!ba
y/\n_/_\n/;s/^/_/
:b
s/\(_[^_]*_{\)\([^}]*\)\(_[^_}]*\)\(_[^}]*\)\(_}.*\)\1\([^}]*\)\3_/\1\2\3\4\5\1\6_/;tb
:c
s/\(_[^_]*_{\)\([^}]*\)_}\(.*\)\1\([^}]*\)_}/\1\2\4_}\3/;tc
s/^_//
y/\n_/_\n/' yourfile
выполняет свою работу, но я должен признать, что регулярные выражения легче писать, чем читать... (-;
perl -alF'/\n[}{]\n/' -0777ne '
for ( 0.. $#F/2 ) {
my $i = 2*$_;
my($k,$v) = @F[$i,$i+1];
if ( exists $h{$k} ) {
$h{$k}.= join $\, grep { ! exists $seen{$k,$_} } split $\, $v;
} else {
push @k, $k;
$seen{$k,$_}++ for split $\, $h{$k} = $v;
}
}
print "$_\n{\n$h{$_}\n}" for @k;
' yourfile
abcd/efgh/a.jar
{
abcd/efgh/a.class
cdef/ghij/b.class
klmn/opqr/c.class
}
lkmn/opqr/b.zip
{
abcd/efgh/a.class
cdef/ghij/b.class
}
Входной файл обрабатывается, а затем разбивается на поля на основе разделителя полей, указанного в опции -F
. Мы получим четное количество элементов в массиве @F
. Затем четные номера используются как ключи хеша %h
, в то время как их соответствие. значения берутся из следующего нечетного значения.
Хэш %h
заполняется путем разделения элементов с нечетными номерами на разделитель записей ($\ = \n ). В то же время мы помещаем ключ в массив @k
, чтобы мы могли получить элементы хеша в том порядке, в котором они были обнаружены.
Все это время используются только те нечетные элементы, которые еще не видны.