I have access to unix server from Putty application. Can anyone tell me how can I view/print all the files and directories inside a directory.
I tried below by searching internet and not working. Not sure what actually they do!
find ./ -type d | awk -F "/" '{ ld=0x2500; lt=0x251c; ll=0x2502; for (i=1; i<=NF-2; i++){printf "%c ",ll} printf "%c%c %s\n",lt,ld,$NF }'
and this
ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
The tool tree will help you, while at it, you might also want to install pstree.
19:38:05 dusted#mono~
$ tree test
test
├── a
│ ├── 1
│ ├── 2
│ └── 3
├── b
│ ├── 1
│ ├── b
│ └── c
├── b-files.txt
├── new-b-files.txt
├── newer-b-files.txt
└── test
2 directories, 10 files
Hey there I did a little searching and stumbled upon a site that explains what you are asking. Let us know if this leads you in the right direction...http://www.centerkey.com/tree/
The 'find' command should do the job:
find /path/to/directory
If you want more information for each entry, you can combine 'find' with 'ls' like this:
find /path/to/directory -exec ls -ld "{}" \;
Related
I am using the following command
zmv -n -Q '(**/)(*[[:upper:]]*)(/)' '${1}${(L)${2//(#b)([[:upper:]])/-$match[1]}#-}'
to transform
% tree
.
├── EmptyFile.txt
├── FirstDirectoryName
│ ├── FourthDirectoryName
│ ├── secondDirectoryName
│ └── thirdDirectoryName
├── FourthDirectoryName
├── secondDirectoryName
└── thirdDirectoryName
To
% tree
.
├── EmptyFile.txt
├── first-directory-name
│ ├── fourth-directory-name
│ ├── second-directory-name
│ └── third-directory-name
├── fourth-directory-name
├── second-directory-name
└── third-directory-name
However there is a small problem.
I do not want to lowercase if there are more than one consecutive uppercase letters. I just want to put - behind the capital letters given it is not in the beginning.
% tree
.
├── DDDDDDD
├── FirstFolderToRename
│ ├── DDDDDDD
│ └── ThisIsDDDDD
├── secondFolderToRename
│ ├── DDDDDDD
│ └── ThisIsDDDDD
└── ThisIsDDDDD
Current Output
% zmv -n -Q '(**/)(*[[:upper:]]*)(/)' '${1}${(L)${2//(#b)([[:upper:]])/-$match[1]}#-}'
mv -- FirstFolderToRename/DDDDDDD FirstFolderToRename/d-d-d-d-d-d-d
mv -- FirstFolderToRename/ThisIsDDDDD FirstFolderToRename/this-is-d-d-d-d-d
mv -- secondFolderToRename/DDDDDDD secondFolderToRename/d-d-d-d-d-d-d
mv -- secondFolderToRename/ThisIsDDDDD secondFolderToRename/this-is-d-d-d-d-d
mv -- DDDDDDD d-d-d-d-d-d-d
mv -- FirstFolderToRename first-folder-to-rename
mv -- secondFolderToRename second-folder-to-rename
mv -- ThisIsDDDDD this-is-d-d-d-d-d
Expected Output
mv -- FirstFolderToRename/DDDDDDD FirstFolderToRename/DDDDDDD
mv -- FirstFolderToRename/ThisIsDDDDD FirstFolderToRename/this-is-DDDDD
mv -- secondFolderToRename/DDDDDDD secondFolderToRename/DDDDDDD
mv -- secondFolderToRename/ThisIsDDDDD secondFolderToRename/this-is-DDDDD
mv -- DDDDDDD DDDDDDD
mv -- FirstFolderToRename first-folder-to-rename
mv -- secondFolderToRename second-folder-to-rename
mv -- ThisIsDDDDD this-is-DDDDD
Specify one or more upper case characters. That is [[:upper:]]## with zsh's extended globbing (which zmv uses). ## is similar to regex + quantifier. A single # is zero or more, similar to regex *.
zmv -n -Q '(**/)(*[[:upper:]]*)(/)' '${1}${(L)${2//(#b)([[:upper:]]##)/-$match[1]}#-}'
Optionally, convert leading upper case characters separately instead of removing initial - afterwards:
${1}${(LM)2##[[:upper:]]#}${(L)${2##[[:upper:]]#}//(#b)([[:upper:]]##)/-$match[1]}
From linuxquestions
function CamelOrPascalToKebab() {
zmv -Q '(**/)(*[A-Z]*)(/)' '$1${2//(#b)([a-z])([A-Z])/$match[1]-$match[2]}'
zmv -Q '(**/)(*[A-Z][a-z]*)(/)' '$1${2//(#m)[A-Z][a-z]/${(L)MATCH}}'
}
I was at a code interview which I failed, but I'm trying to understand it anyways.
From root, I was supposed to first get all html files and tar them on a single command.
After I failed, I was able to do it on my own like this:
find . -name "*.js" | xargs tar -cvf tar.tar
My problem is, it mimics the whole tree structure of the system. I wanted a solution that would put all the files on the same level, if I were to run on a folder with
-
| a.js
| b.html
| c.js
|_ folder
| g.html
My resulting tar ends up having a folder called folder with g.html in it. When ran from root, this looks terrible
root#i5-cpu:~/work_area/php# tree d1
d1
├── d2
│ ├── f2_1.js
│ └── f2_2.js
├── f1_1.js
└── f1_2.js
1 directory, 4 files
root#i5-cpu:~/work_area/php# find . -name "\*.js" | xargs tar -cvf tar.tar --transform='s,.*/,,'
./d1/d2/f2_1.js
./d1/d2/f2_2.js
./d1/f1_1.js
./d1/f1_2.js
root#i5-cpu:~/work_area/php# tar -tvf tar.tar
-rw-rw-rw- root/root 0 2019-01-17 01:12 f2_1.js
-rw-rw-rw- root/root 0 2019-01-17 01:12 f2_2.js
-rw-rw-rw- root/root 0 2019-01-17 01:11 f1_1.js
-rw-rw-rw- root/root 0 2019-01-17 01:11 f1_2.js
Check this page https://www.gnu.org/software/tar/manual/html_section/tar_51.html
The examples with --transform
I have these JSON files in a large directory structure. Some are just "abc.json" and some the added ".finished". I want to rsync only the files without ".finished".
$ find
.
./a
./a/abc.json.finished
./a/abc.json <-- this file
./a/index.html
./a/somefile.css
./b
./b/abc.json.finished
./b/abc.json <-- this file
Sample rsync command that copies all the "abc.json" AND the "abc.json.finished". I just want the "abc.json".
$ rsync --exclude="finished" --include="*c.json" --recursive \
--verbose --dry-run . server:/tmp/rsync
sending incremental file list
created directory /tmp/rsync
./
a/
a/abc.json
a/abc.json.finished
a/index.html
a/somefile.css
b/
b/abc.json
b/abc.json.finished
sent 212 bytes received 72 bytes 113.60 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)
Update: Added more files to the folders. HTML files, CSS and other files are present in my scenario. Only files ending in "c.json" should be transferred.
Scenario can be recreated with the following commands:
mkdir a
touch a/abc.json.finished
touch a/abc.json
touch a/index.html
touch a/somefile.css
mkdir b
touch b/abc.json.finished
touch b/abc.json
Try the following command. It assumes that you also want to replicate the source directory tree, (for any directories containing files which end with c.json), in the destination location:
$ rsync --include="*c.json" --exclude="*.*" --recursive \
--verbose --dry-run . server:/tmp/rsync
Explanation of command:
--include="*c.json" includes only assets whose name ends with c.json
--exclude="*.*" excludes all other assets (i.e. assets whose name includes a dot .)
--recursive recurse into directories.
--verbose log the results to the console.
--dry-run shows what would have been copied, without actually copying the files. This option/flag should be omitted to actually perform the copy task.
. the path to the source directory.
server:/tmp/rsync the path to the destination directory.
EDIT: Unfortunately, the command provided above also copies files whose filename does not include a dot character. To avoid this consider utlizing both rsync and find as follows:
$ rsync --dry-run --verbose --files-from=<(find ./ -name "*c.json") \
./ server:/tmp/rsync
This utilizes process substitution, i.e. <(list), to pass the output from the find command to the --files-from= option/flag of the rsync command.
source tree
.
├── a
│ ├── abc.json
│ ├── abc.json.finished.json
│ ├── index.html
│ └── somefile.css
└── b
├── abc.json
└── abc.json.finished.json
resultant destination tree
server
└── tmp
└── rsync
├── a
│ └── abc.json
└── b
└── abc.json
A hacky solution is use grep and create a file containing all file names we want to transfer.
find |grep "c.json$" > rsync-files
rsync --files-from=rsync-files --verbose --recursive --compress --dry-run \
./ \
server:/tmp/rsync
rm rsync-files
Content of 'rsync-files':
./a/abc.json
./b/abc.json
Output when running rsync command:
sending incremental file list
created directory /tmp/rsync
./
a/
a/abc.json
b/
b/abc.json
I'm quite new to makefile but I still cannot understand how to set up the subdirectories of my source files.
My directory tree is:
i18n/
src/
engine/
graphics/ (currently only directory used)
I'm using this premade Makefile:
TARGET = caventure
LIBS = -lSDL2
CC = g++
CFLAGS = -Wall
TGTDIR = build
.PHONY: default all clean
default: $(TARGET)
all: default
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp))
HEADERS = $(wildcard *.h)
%.o: %.cpp $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -Wall $(LIBS) -o $(TGTDIR)/$(TARGET)
clean:
-rm -f *.o
-rm -f $(TARGET)
GNU make's wildcard function does not recursively visit all subdirectories.
You need a recursive variant of it, which can be implemented as described in this answer:
https://stackoverflow.com/a/18258352/1221106
So, instead of $(wildcard *.cpp) you need to use that recursive wildcard function.
Another simpler way of finding files recursively might be to just use find.
For example, if you have a layout like this.
$ tree .
.
├── d1
│ └── foo.txt
├── d2
│ ├── d4
│ │ └── foo.txt
│ └── foo.txt
├── d3
│ └── foo.txt
└── Makefile
You could write a Makefile like this.
index.txt: $(shell find . -name "*.txt")
echo $^
Which prints this.
$ make
echo d2/d4/foo.txt d2/foo.txt d1/foo.txt d3/foo.txt
d2/d4/foo.txt d2/foo.txt d1/foo.txt d3/foo.txt
I'm currently in a situation where I have very limited access to a server, but need to upload and download a significant amount of files contained within a single directory structure. I don't have SSH access, so I can't use SCP - and rsync isn't an option either unfortunately.
I'm currently using ncftpput, which is great but seems to be quite slow (in spite of a fast connection).
Is there an alternative / better method I could look into?
(Please accept my apologies if this has been covered, I did a quick search prior to posting but didn't find anything that specifically answered my question)
Try using LFTP:
http://lftp.yar.ru/
or YAFC:
http://yafc.sourceforge.net/index.php
If you have a good connection, I would recommend mounting the ftp server via the GNOME or KDE file managers, or else using CurlFtpFS. Then you can treat it like just another folder.
I'm not familiar with ncftpput. For non-interactive FTP, I've always used the Perl Net::FTP module -- http://perldoc.perl.org/Net/FTP.html
This will be faster because you can login, then do all the transfers at once (it seems from a cursory glance that you execute ncftpput once for each file get/put).
Just remember to NEVER use ASCII mangling! This is the default, so use:
$ftp->binary
ASCII mangling needs to die in the same fire with MySQL automatic-timezone-interpreting.
Since I always end up having a problem with this, I'll post my notes here:
One thing I always get to confuse is the syntax; so below there is a bash tester script which creates some temporary directories, then starts a temporary ftp server, and compares rsync (in plain local file mode, as it doesn't support ftp) with lftp and ftpsync.
The thing is - you can use rsync /path/to/local /path/to/remote/, and rsync will automatically figure out, that you want a local subdirectory created under remote; however, for lftp or ftpsync you have to specify the target directory manually, as in ... /path/to/local /path/to/remote/local (if it doesn't exist it will be created).
You can find the ftpserver-cli.py in How do I temporarily run an FTP server? - Ask Ubuntu; and ftpsync is here: FTPsync (however, note it is buggy; see also Search/grep ftp remote filenames - Unix & Linux Stack Exchange);
Here is a shortened output of the puttest.sh script, showing the recursive put behavior in different cases:
$ bash puttest.sh
Recreate directories; populate loctest, keep srvtest empty:
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
/tmp/loctest
├── .git
│ └── tempa2.txt
└── tempa1.txt
*NOTE, rsync can automatically figure out parent dir:
+ rsync -a --exclude '*.git*' /tmp/loctest /tmp/srvtest/
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── loctest
└── tempa1.txt
/tmp/loctest
├── .git
│ └── tempa2.txt
└── tempa1.txt
cleanup:
+ rm -rf /tmp/srvtest/loctest
Start a temporary ftp server:
+ sudo bash -c 'python /path/to/pyftpdlib/ftpserver-cli.py --username=user --password=12345 --directory=/tmp/srvtest &'
+ sleep 1
Using: user: user pass: 12345 port: 21 dir: /tmp/srvtest
[I 14-03-02 23:24:01] >>> starting FTP server on 127.0.0.1:21, pid=21549 <<<
[I 14-03-02 23:24:01] poller: <class 'pyftpdlib.ioloop.Epoll'>
[I 14-03-02 23:24:01] masquerade (NAT) address: None
[I 14-03-02 23:24:01] passive ports: None
[I 14-03-02 23:24:01] use sendfile(2): False
test with lftp:
*NOTE, lftp syncs *contents* of local dir (rsync-like syntax doesn't create target dir):
+ lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest / ; exit' -u user,12345 127.0.0.1
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── tempa1.txt
/tmp/loctest
├── .git
│ └── tempa2.txt
└── tempa1.txt
cleanup:
+ rm -rf /tmp/srvtest/tempa1.txt
*NOTE, specify lftp target dir explicitly (will be autocreated):
+ lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest /loctest ; exit' -u user,12345 127.0.0.1
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── loctest
└── tempa1.txt
/tmp/loctest
├── .git
│ └── tempa2.txt
└── tempa1.txt
cleanup:
+ sudo rm -rf /tmp/srvtest/loctest
*NOTE, ftpsync syncs *contents* of local dir (rsync-like syntax doesn't create target dir); also info mode -i is buggy (it puts, although it shouldn't):
*NOTE, ftpsync --ignoremask is for older unused code; use --exclude instead (but it is buggy; need to change in source)
+ /path/to/ftpsync/ftpsync -i -d '--exclude=.*\.git.*' /tmp/loctest ftp://user:12345#127.0.0.1/
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── tempa1.txt
/tmp/loctest
├── .git
│ └── tempa2.txt
└── tempa1.txt
cleanup:
+ sudo rm -rf /tmp/srvtest/tempa1.txt
*NOTE, specify ftpsync target dir explicitly (will be autocreated):
+ /path/to/ftpsync/ftpsync -i -d '--exclude=.*\.git.*' /tmp/loctest ftp://user:12345#127.0.0.1/loctest
show dirs:
+ tree --noreport -a /tmp/srvtest /tmp/loctest
/tmp/srvtest
└── loctest
└── tempa1.txt
/tmp/loctest
├── .git
│ └── tempa2.txt
└── tempa1.txt
cleanup:
+ sudo rm -rf /tmp/srvtest/loctest
+ sudo pkill -f ftpserver-cli.py
And, here is the puttest.sh script:
#!/usr/bin/env bash
set -x
# change these to match your installations:
FTPSRVCLIPATH="/path/to/pyftpdlib"
FTPSYNCPATH="/path/to/ftpsync"
{ echo "Recreate directories; populate loctest, keep srvtest empty:"; } 2>/dev/null
sudo rm -rf /tmp/srvtest /tmp/loctest
mkdir /tmp/srvtest
mkdir -p /tmp/loctest/.git
echo aaa > /tmp/loctest/tempa1.txt
echo aaa > /tmp/loctest/.git/tempa2.txt
{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest
{ echo -e "\n*NOTE, rsync can automatically figure out parent dir:"; } 2>/dev/null
rsync -a --exclude '*.git*' /tmp/loctest /tmp/srvtest/
{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest
{ echo "cleanup:"; } 2>/dev/null
rm -rf /tmp/srvtest/*
{ echo -e "\nStart a temporary ftp server:"; } 2>/dev/null
# https://askubuntu.com/questions/17084/how-do-i-temporarily-run-an-ftp-server
sudo bash -c "python $FTPSRVCLIPATH/ftpserver-cli.py --username=user --password=12345 --directory=/tmp/srvtest &"
sleep 1
{ echo "test with lftp:"; } 2>/dev/null
# see http://russbrooks.com/2010/11/19/lftp-cheetsheet
# The -R switch means "reverse mirror" which means "put" [upload].
{ echo -e "\n*NOTE, lftp syncs *contents* of local dir (rsync-like syntax doesn't create target dir):"; } 2>/dev/null
lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest / ; exit' -u user,12345 127.0.0.1
{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest
{ echo "cleanup:"; } 2>/dev/null
rm -rf /tmp/srvtest/*
{ echo -e "\n*NOTE, specify lftp target dir explicitly (will be autocreated):"; } 2>/dev/null
lftp -e 'mirror -R -x ".*\.git.*" /tmp/loctest /loctest ; exit' -u user,12345 127.0.0.1
{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest
{ echo "cleanup:"; } 2>/dev/null
sudo rm -rf /tmp/srvtest/*
{ echo -e "\n*NOTE, ftpsync syncs *contents* of local dir (rsync-like syntax doesn't create target dir); also info mode -i is buggy (it puts, although it shouldn't):"; } 2>/dev/null
{ echo -e "\n*NOTE, ftpsync --ignoremask is for older unused code; use --exclude instead (but it is buggy; need to change ` 'exclude=s' => \$opt::exclude,` in source)"; } 2>/dev/null
$FTPSYNCPATH/ftpsync -i -d --exclude='.*\.git.*' /tmp/loctest ftp://user:12345#127.0.0.1/
{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest
{ echo "cleanup:"; } 2>/dev/null
sudo rm -rf /tmp/srvtest/*
{ echo -e "\n*NOTE, specify ftpsync target dir explicitly (will be autocreated):"; } 2>/dev/null
$FTPSYNCPATH/ftpsync -i -d --exclude='.*\.git.*' /tmp/loctest ftp://user:12345#127.0.0.1/loctest
{ echo "show dirs:"; } 2>/dev/null
tree --noreport -a /tmp/srvtest /tmp/loctest
{ echo "cleanup:"; } 2>/dev/null
sudo rm -rf /tmp/srvtest/*
sudo pkill -f ftpserver-cli.py
{ set +x; } 2>/dev/null
No mention of ncftp?
In Ubuntu, sudo apt install ncftp