Dla przypomnienia wersja wklejonej przeze mnie wersji wymaga argumentu „-” na końcu, aby nakazać jej odczytanie ze STDIN. np. ls -1 | paste -s -d ":" - Nie jestem pewien, czy jest to uniwersalne dla wszystkich wersji pasty
Andy White
4
ten jest lepszy, ponieważ pozwala na pusty ogranicznik :)
Yura Purbeev
2
Uwaga pastedostaje -(standardowe wejście) domyślnie, przynajmniej na mój paste (GNU coreutils) 8.22.
fedorqui „SO przestań krzywdzić”
1
właśnie go głosowałem, to jest i teraz ma tyle samo głosów co wybrana odpowiedź. TO ODPOWIEDŹ. brak ogranicznika końcowego
thebugfinder
1
Pusty separator można określić za pomocą "\0", więc paste -sd "\0" -działało dla mnie!
Brad Parks,
379
EDYCJA : Po prostu „ ls -m ” Jeśli chcesz, aby separator był przecinkiem
Ach, siła i prostota!
ls -1| tr '\n'','
Zmień przecinek „ , ” na cokolwiek chcesz. Pamiętaj, że obejmuje to „przecinek końcowy”
To nie zajmie się plikami z białymi spacjami w nazwie. Spróbuj tego: dir = / tmp / testdir; rm -rf $ katalog i & mkdir $ katalog i & cd / $ katalog i & touch "to jest plik" ten_ kolejny_plik i & ls -1 && files = ($ (ls -1)) && list = $ {pliki [@] /% / ,} && list = $ {list% *,} && echo $ list
dimir
1
@dimir: Wiele odpowiedzi na to pytanie cierpi z powodu tego problemu. Zredagowałem swoją odpowiedź, aby zezwolić na nazwy plików zawierające tabulatory lub spacje, ale nie znaki nowej linii.
Wstrzymano do odwołania.
Twoja wersja bash również cierpi z powodu rozszerzenia nazw ścieżek. Aby zbudować tablicę z liniami należy rozważyć zastosowanie mapfile(Bash ≥ 4) jako: mapfile -t files < <(ls -1). Nie musisz się bawić IFS. I jest też krótszy.
gniourf_gniourf
A gdy masz tablicę można wykorzystać IFSdo przyłączenia się do pola: saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS. Lub użyj innej metody, jeśli chcesz separator zawierający więcej niż jeden znak.
gniourf_gniourf
1
@gniourf_gniourf: Dołączyłem twoje sugestie do mojej odpowiedzi. Dzięki.
Wstrzymano do odwołania.
24
Myślę, że ten jest niesamowity
ls -1| awk 'ORS=","'
ORS jest „separatorem rekordów wyjściowych”, więc teraz linie zostaną połączone przecinkiem.
Czy masz więcej informacji na temat tego, jak setdziała? Dla mnie wygląda to trochę jak voodoo. płytki przegląd man setnie dostarczył mi również wielu informacji.
Ehtesh Choudhury,
3
Jeśli podasz setkilka argumentów, ale nie masz opcji, ustawia parametry pozycyjne (1 $, 2 $, ...). --jest do ochrony setna wypadek, gdyby pierwszy argument (lub nazwa pliku w tym przypadku) zaczął się od myślnika. Zobacz opis --opcji w help set. Uważam, że parametry pozycyjne są wygodnym sposobem obsługi listy rzeczy. Mógłbym również zaimplementować to z tablicą:output=$( files=(*); IFS=,; echo "${files[*]}" )
glenn jackman
Jest to świetne, ponieważ nie wymaga wykonywania żadnych dodatkowych programów i działa z nazwami plików, które zawierają spacje, a nawet znaki nowej linii.
Eric
1
@EhteshChoudhury Jak type setpowie, set is a shell builtin. Więc man setnie pomoże, ale help setzrobi. Odpowiedź: „- Przypisz pozostałe argumenty do parametrów pozycyjnych.”
Stéphane Gourichon
Po set -- *. Opóźniając ekspansję *jednego poziomu można uzyskać poprawny wynik bez konieczności powłoki sub: IFS=',' eval echo '"$*"'. Oczywiście to zmieni parametry pozycyjne.
Izaak
13
Parsowanie lsw ogóle nie jest zalecane , więc alternatywnym lepszym sposobem jest użycie find, na przykład:
OP chciał dowolnego separatora, więc nadal będziesz potrzebował tr, aby przekonwertować przecinki. Dodaje również spację po przecinkach, tj. Plik1, plik2, plik3
rob
więc używając ls -mi, traby usunąć spację po przecinku, zrobiłbyśls -m | tr -d ' '
Andy
2
użycie tr usunie spacje w nazwach plików. lepiej użyćsed 's/, /,/g
Uwaga: ujemne liczby bajtów są obsługiwane tylko w niektórych wersjach head, więc to nie będzie działać np. W macos.
Peter
Dzięki za wskazanie tego. Dodałem obejście dla MacOS.
Aleksander Stelmaczonek
4
Sed sposób
sed -e ':a; N; $!ba; s/\n/,/g'# :a # label called 'a'# N # append next line into Pattern Space (see info sed)# $!ba # if it's the last line ($) do not (!) jump to (b) label :a (a) - break loop# s/\n/,/g # any substitution you want
Uwaga :
Jest to złożoność liniowa, zastępująca tylko raz po dodaniu wszystkich linii do Przestrzeni Wzorów sed.
@ Odpowiedź AnandRajaseki i inne podobne odpowiedzi, takie jak tutaj , to O (n²), ponieważ sed musi zastępować za każdym razem, gdy do Przestrzeni Wzorów dodawana jest nowa linia.
Porównywać,
seq 1100000| sed ':a; N; $!ba; s/\n/,/g'| head -c 80# linear, in less than 0.1s
seq 1100000| sed ':a; /$/N; s/\n/,/; ta'| head -c 80# quadratic, hung
-dokreśla separator wejściowy z GNU xargs, więc nie będzie działać. Drugi przykład pokazuje ten sam problem, co inne rozwiązania ogranicznika błądzenia na końcu.
Thor
3
sed -e :a -e '/$/N; s/\n/\\n/; ta'[filename]
Wyjaśnienie:
-e- oznacza polecenie do wykonania :a- jest etykietą /$/N- określa zakres dopasowania dla bieżącej i linii (N) ext s/\n/\\n/;- zamienia wszystkie EOL na\n ta; - goto label a, jeśli dopasowanie się powiedzie
ls -1 | paste -s -d ":" -
Nie jestem pewien, czy jest to uniwersalne dla wszystkich wersji pastypaste
dostaje-
(standardowe wejście) domyślnie, przynajmniej na mójpaste (GNU coreutils) 8.22
."\0"
, więcpaste -sd "\0" -
działało dla mnie!Ach, siła i prostota!
Zmień przecinek „ , ” na cokolwiek chcesz. Pamiętaj, że obejmuje to „przecinek końcowy”
źródło
\n
w sobie, to również to zastąpi.ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sed
być trochę bardziej wydajny dzięki postaci ze znacznikiem końcowym:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sed
potr
wydaje się po prostu usunąć ostatni symbol wydaje się nieuzasadnione. Idę zls -1 | tr '\n' ',' | head -c -1
To zastępuje ostatni przecinek nową linią:
ls -m
zawiera znaki nowej linii na znaku szerokości ekranu (na przykład 80.).Głównie Bash (tylko
ls
zewnętrzny):Używanie
readarray
(akamapfile
) w Bash 4:Dzięki gniourf_gniourf za sugestie.
źródło
mapfile
(Bash ≥ 4) jako:mapfile -t files < <(ls -1)
. Nie musisz się bawićIFS
. I jest też krótszy.IFS
do przyłączenia się do pola:saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS
. Lub użyj innej metody, jeśli chcesz separator zawierający więcej niż jeden znak.Myślę, że ten jest niesamowity
ORS jest „separatorem rekordów wyjściowych”, więc teraz linie zostaną połączone przecinkiem.
źródło
" OR "
)Połączenie ustawienia
IFS
i użycia"$*"
może robić, co chcesz. Używam podpowłoki, więc nie przeszkadzam w $ IFS tej powłokiAby uchwycić wynik,
źródło
set
działa? Dla mnie wygląda to trochę jak voodoo. płytki przeglądman set
nie dostarczył mi również wielu informacji.set
kilka argumentów, ale nie masz opcji, ustawia parametry pozycyjne (1 $, 2 $, ...).--
jest do ochronyset
na wypadek, gdyby pierwszy argument (lub nazwa pliku w tym przypadku) zaczął się od myślnika. Zobacz opis--
opcji whelp set
. Uważam, że parametry pozycyjne są wygodnym sposobem obsługi listy rzeczy. Mógłbym również zaimplementować to z tablicą:output=$( files=(*); IFS=,; echo "${files[*]}" )
type set
powie,set is a shell builtin
. Więcman set
nie pomoże, alehelp set
zrobi. Odpowiedź: „- Przypisz pozostałe argumenty do parametrów pozycyjnych.”set -- *
. Opóźniając ekspansję*
jednego poziomu można uzyskać poprawny wynik bez konieczności powłoki sub:IFS=',' eval echo '"$*"'
. Oczywiście to zmieni parametry pozycyjne.Parsowanie
ls
w ogóle nie jest zalecane , więc alternatywnym lepszym sposobem jest użyciefind
, na przykład:Lub za pomocą
find
ipaste
:Aby uzyskać ogólne łączenie wielu linii (niezwiązane z systemem plików), zaznacz: Zwięzłe i przenośne „łączenie” w wierszu poleceń systemu Unix .
źródło
Nie wymyślaj koła ponownie.
Robi dokładnie to.
źródło
ls -m
i,tr
aby usunąć spację po przecinku, zrobiłbyśls -m | tr -d ' '
sed 's/, /,/g
po prostu bash
źródło
|
pogryza końcowego , @camh.bash
i gnu coreutilsprintf
printf -v
będzie działać tylko w trybie bash, podczas gdy przedstawiona odpowiedź działa na wielu typach powłok.|
, pod warunkiem, że obie linie są używane:printf -v mystring "%s|" * ; echo ${mystring%|}
.To polecenie jest przeznaczone dla fanów PERL:
Tutaj 40 to ósemkowy kod ascii dla przestrzeni.
-p przetworzy wiersz po wierszu i wydrukuje
-l zajmie się zastąpieniem końcowego znaku \ n przez zapewniany przez nas znak ascii.
-e ma poinformować PERL, że wykonujemy wykonanie wiersza poleceń.
0 oznacza, że tak naprawdę nie ma polecenia do wykonania.
perl -e0 jest taki sam jak perl -e ''
źródło
Aby uniknąć potencjalnego pomyłki nowego wiersza dla tr, możemy dodać flagę -b do ls:
źródło
Wygląda na to, że odpowiedzi już istnieją.
Jeśli chcesz
a, b, c
formatować, użyjls -m
(odpowiedź Tulainsa Córdova )Lub jeśli chcesz
a b c
formatować, użyjls | xargs
(uproszczonej wersji odpowiedzi Chrisa J. )Lub jeśli chcesz jakikolwiek inny ogranicznik
|
, użyjls | paste -sd'|'
(zastosowanie odpowiedzi Artem )źródło
Dodając do odpowiedzi majkinetor, oto sposób usuwania ogranicznika końcowego (ponieważ nie mogę jeszcze skomentować pod jego odpowiedzią):
Po prostu usuń tyle bajtów końcowych, ile liczy Twój separator.
Podoba mi się to podejście, ponieważ mogę używać ograniczników wieloznakowych + innych korzyści
awk
:EDYTOWAĆ
Jak zauważył Peter, ujemna liczba bajtów nie jest obsługiwana w natywnej wersji głowy MacOS. Można to jednak łatwo naprawić.
Najpierw zainstaluj
coreutils
. „Narzędzia GNU Core to podstawowe narzędzia do obsługi plików, powłok i tekstów w systemie operacyjnym GNU.”Polecenia również dostarczane przez MacOS są instalowane z prefiksem „g”. Na przykład
gls
.Gdy to zrobisz, możesz użyć,
ghead
który ma ujemną liczbę bajtów lub lepiej, zrobić alias:źródło
Sed sposób
Uwaga :
Jest to złożoność liniowa, zastępująca tylko raz po dodaniu wszystkich linii do Przestrzeni Wzorów sed.
@ Odpowiedź AnandRajaseki i inne podobne odpowiedzi, takie jak tutaj , to O (n²), ponieważ sed musi zastępować za każdym razem, gdy do Przestrzeni Wzorów dodawana jest nowa linia.
Porównywać,
źródło
Jeśli twoja wersja xargs obsługuje flagę -d, to powinno działać
-d jest flagą separatora
Jeśli nie masz -d, możesz wypróbować następujące
Pierwsze xargs pozwala określić ogranicznik, który w tym przykładzie jest przecinkiem.
źródło
-d
określa separator wejściowy z GNU xargs, więc nie będzie działać. Drugi przykład pokazuje ten sam problem, co inne rozwiązania ogranicznika błądzenia na końcu.Wyjaśnienie:
-e
- oznacza polecenie do wykonania:a
- jest etykietą/$/N
- określa zakres dopasowania dla bieżącej i linii (N) exts/\n/\\n/;
- zamienia wszystkie EOL na\n
ta;
- goto label a, jeśli dopasowanie się powiedzieZaczerpnięte z mojego bloga .
źródło
Możesz użyć:
źródło
ls
tworzy jedną kolumnę wyjściową po podłączeniu do rury, więc-1
jest nadmiarowa.Oto kolejna odpowiedź Perla, wykorzystująca wbudowaną
join
funkcję, która nie pozostawia ogranicznika końcowego:Niejasne
-0777
zmusza Perla do odczytania wszystkich danych wejściowych przed uruchomieniem programu.sed alternatywa, która nie pozostawia ogranicznika końcowego
źródło
ls
ma opcję-m
ograniczenia danych wyjściowych", "
przecinkiem i spacją.potokowanie tego wyniku w
tr
celu usunięcia spacji lub przecinka pozwoli na ponowne potokowanie wyniku wtr
celu zastąpienia ogranicznika.w moim przykładzie zastępuję separator
,
separatorem;
zamień na
;
dowolny ogranicznik jednego znaku , ponieważ tr uwzględnia tylko pierwszy znak w ciągach, które przekazujesz jako argumenty.źródło
Możesz użyć chomp, aby scalić wiele linii w jedną linię:
perl -e 'while (<>) {if (/ \ $ /) {chomp; } print;} 'bad0> test
wstaw warunek przerwania linii w instrukcji if. Może to być znak specjalny lub dowolny separator.
źródło
Wersja Quick Perl z końcowym ukośnikiem:
Wytłumaczyć:
źródło